1

我正在尝试创建一个新的作业正文并使用 HttpWebRequest 对象将此正文发布到 BigQuery。正文包含两部分,即。来自 csv 的定义和内容。我不知道我卡在哪里并且我收到一个错误:-“远程服务器返回一个错误:(400)错误请求”。我能够使用服务帐户成功生成访问令牌。

这是我的代码:-

        string strURL = "https://www.googleapis.com/upload/bigquery/v2/projects/" + strProjId + "/jobs";
        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(strURL);
        request.ContentType = "multipart/related; boundary=xxx";
        request.Headers.Add(HttpRequestHeader.Authorization, strAccessToken);
        request.Method = "POST";
        //string strHeader = "{'Content-Type': 'multipart/related; boundary=xxx', 'Authorization': 'Bearer " + strAccessToken + "'}";
        string strJob = "--xxx" + "\n" +
                                "Content-Type: application/json; charset=UTF-8" + "\n" +
                                "{" + "\n" +
                                "'kind' : 'bigquery#job' ," + "\n" +
                                "'Id' : 'testJob' ," + "\n" +
                                  "'configuration': {" + "\n" +
                                    "'load': {" + "\n" +
                                     "'sourceFormat':'CSV'," + "\n" +
                                        "'schema': {" + "\n" +
                                        "'fields': [" + "\n" +
                                            "{'name':'Event_strLanguage','type':'STRING'}" + "\n" +
                                            "{'name':'Event_strTitle','type':'STRING'}," + "\n" +
                                            "{'name':'Event_dtmReleaseDate','type':'STRING'}," + "\n" +
                                        "]" + "\n" +
                                        "}," + "\n" +
                                        "'destinationTable': {" + "\n" +
                                        "'projectId': '" + strProjId + "'," + "\n" +
                                        "'datasetId': '" + strDatasetId + "'," + "\n" +
                                        "'tableId': 'tblEvents'" + "\n" +
                                        "}," + "\n" +
                                        "'fieldDelimiter':'|', " + "\n" +
                                    "}" + "\n" +
                                    "}" + "\n" +
                                "}" + "\n" +
                                "--xxx" + "\n" +
                                "Content-Type: application/octet-stream";

        StringBuilder sbrData = new StringBuilder();
        sbrData.AppendLine("Hindi|ABC|2008-01-11 00:00:00");//from CSV
        sbrData.AppendLine("Hindi|LMN|2008-02-20 00:00:00");//from CSV
        sbrData.AppendLine("Hindi|XYZ|2009-03-27 00:00:00");//from CSV
        StringBuilder sbrReqBody = new StringBuilder();
        sbrReqBody.Append(strJob + "\r\n" + sbrData + "--xxx--");

        byte[] bytes = Encoding.ASCII.GetBytes(sbrReqBody.ToString());
        request.ContentLength = bytes.Length;
        Stream requestStream = request.GetRequestStream();
        requestStream.Write(bytes, 0, bytes.Length);
        WebResponse resp = request.GetResponse();
        Stream stream = resp.GetResponseStream();
        StreamReader reader = new StreamReader(stream);
        stream.Dispose();
        reader.Dispose();
        var result2 = reader.ReadToEnd();

我编辑了代码,仍然收到错误 400 错误请求:-

 string strDataBoundary = "xxx";
 string strFooter = "\r\n--" + strDataBoundary + "--\r\n";
 string strContentType = "multipart/related; boundary=" + strDataBoundary;
 string strURL = "https://www.googleapis.com/upload/bigquery/v2/projects/" + strProjId + "/jobs";

HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(strURL);
            request.Method = "POST";
            request.ContentType = strContentType;
            System.Net.ServicePointManager.Expect100Continue = false;
            request.PreAuthenticate = true;
            request.AuthenticationLevel = System.Net.Security.AuthenticationLevel.MutualAuthRequired;
            request.Headers.Add("Authorization", "Bearer " + strAccessToken); //Supplied OAuth 2.0 Access Token.
            request.KeepAlive = true;

        string strJob = "--" + strDataBoundary + "\r\n" +
                                "Content-Type: application/json; charset=UTF-8" + "\r\n" +
                                "{" + "\r\n" +
                                "\"kind\" : \"bigquery#job\" ," + "\r\n" +
                                "\"Id\" : \"testJob\" ," + "\r\n" +
                                  "\"configuration\": {" + "\r\n" +
                                    "\"load\": {" + "\r\n" +
                                        "\"destinationTable\": {" + "\r\n" +
                                        "\"projectId\": \"" + strProjId + "\"," + "\r\n" +
                                        "\"datasetId\": \"" + strDatasetId + "\"," + "\r\n" +
                                        "\"tableId\": \"tblEvents\"" + "\r\n" +
                                        "}," + "\r\n" +
                                        "\"fieldDelimiter\":\"|\", " + "\r\n" +
                                    "}" + "\r\n" +
                                    "}" + "\r\n" +
                                "}" + "\r\n" +
                                "--" + strDataBoundary  + "\r\n" +
                                "Content-Type: application/octet-stream";

        FileStream objFS = new FileStream("D:\\Events.csv", FileMode.Open, FileAccess.Read);
        byte[] objFileData = new byte[objFS.Length];
        objFS.Read(objFileData, 0, objFileData.Length);
        objFS.Close();

        Stream objDataStream = new MemoryStream();
        objDataStream.Write(Encoding.UTF8.GetBytes(strJob), 0, Encoding.UTF8.GetByteCount(strJob));
        objDataStream.Write(objFileData, 0, objFileData.Length);
        objDataStream.Write(Encoding.UTF8.GetBytes(strFooter),0,Encoding.UTF8.GetByteCount(strFooter));

        objDataStream.Position = 0;
        byte[] objStream = new byte[objDataStream.Length];
        objDataStream.Read(objStream, 0, objStream.Length);
        objDataStream.Close();
        request.ContentLength = objStream.Length;

        Stream objReqStream = request.GetRequestStream();
        objReqStream.Write(objStream, 0, objStream.Length);
        objReqStream.Close();

        HttpWebResponse objResp = (HttpWebResponse)request.GetResponse(); 

现在,我正在尝试另一种方式:-

internal class clsGetOAuth2Authentication
    {
        public OAuth2Authenticator<AssertionFlowClient> objGetOAuth2(string strPrivateFilePath, string strPrivateFilePassword, string strServiceAccEmailId,string strScope)
        {
            AuthorizationServerDescription objAuthServerDesc;
            X509Certificate2 objKey;
            AssertionFlowClient objClient;
            OAuth2Authenticator<AssertionFlowClient> objAuth = null;

            string ScopeUrl = "https://www.googleapis.com/auth/" + strScope;
            string strSrvAccEmailId = strServiceAccEmailId; //strSrvAccEmailId: This is the Email Address of the Service Account. 
            string strKeyFile = strPrivateFilePath; //KeyFile: This is the physical path to the key file you downloaded when you created your Service Account.
            string strKeyPassword = (strPrivateFilePassword != "") ? strPrivateFilePassword : "notasecret"; //key_pass: This is probably the password for all key files, but if you're given a different one, use that.

            objAuthServerDesc = GoogleAuthenticationServer.Description; //objAuthServerDesc: Description of the server that will grant Authentiation. 
            objKey = new X509Certificate2(strKeyFile, strKeyPassword, X509KeyStorageFlags.Exportable); //objkey: Load up and decrypt the key.
            objClient = new AssertionFlowClient(objAuthServerDesc, objKey) { ServiceAccountId = strSrvAccEmailId, Scope = ScopeUrl }; //objClient: Using the AssertionFlowClient, because we're logging in with our certificate.
            objAuth = new OAuth2Authenticator<AssertionFlowClient>(objClient, AssertionFlowClient.GetState); //objAuth: Requesting Authentication.
            return objAuth;
        }
    }
//The above class returns OAuth2Authenticator<AssertionFlowClient> object:-

        clsGetOAuth2Authentication objOAuth2 = new clsGetOAuth2Authentication();
        var objAuth = objOAuth2.objGetOAuth2(strKeyFile, strKeyPassword,    strSrvAccEmailId, strScope); //Authentication data returned

        objBQServ = new BigqueryService(objAuth); //Instantiate BigQueryService with Authorization

        TableReference objTblRef = new TableReference();
        objTblRef.ProjectId = strProjId;
        objTblRef.DatasetId = strDatasetId;
        objTblRef.TableId = "tblEvents";

        JobConfigurationLoad objJobConfigLoad = new JobConfigurationLoad();
        objJobConfigLoad.FieldDelimiter = "|";
        objJobConfigLoad.DestinationTable = objTblRef;
        objJobConfigLoad.WriteDisposition = "WRITE_APPEND ";

        JobConfiguration objJobConfig = new JobConfiguration() { Load = objJobConfigLoad };
        Job objJob = new Job() { Configuration = objJobConfig, Kind = "bigquery#jobs", Id = "TestJob" };


        FileStream objFS = new FileStream("D:\\tblEvents2.csv", FileMode.Open, FileAccess.Read);
        byte[] objFileData = new byte[objFS.Length];
        objFS.Read(objFileData, 0, objFileData.Length);
        objFS.Close();

        Stream objDataStream = new MemoryStream();
        objDataStream.Write(objFileData, 0, objFileData.Length);

        objBQServ.Jobs.Insert(objJob, strProjId, objDataStream, "application/octet-stream").Upload(); //Getting error at the Upload() method. Object cannot be initialized. 

请帮我看看这段代码我是否朝着正确的方向前进。

4

1 回答 1

0

乍一看,我认为问题可能在于您似乎正在编码整个请求,而不仅仅是内容本身。我建议使用此处描述的 FileStream 类。

于 2012-11-14T20:07:00.553 回答