使用导入本地CSV文件中的数据,以大查询表的HttpWebRequest POST方法文件、方法、数据、CSV

2023-09-06 16:50:00 作者:等待

我试图创建一个新的工作主体和使用HttpWebRequest对象发布本机构BigQuery中。 主体包含两个部分即。定义和CSV内容。我不知道我是被卡住,我得到一个错误: - 远程服务器返回错误:(400)错误的请求。 我能够使用服务帐户生成访问令牌成功。

I'm trying to create a new job body and posting this body to BigQuery using HttpWebRequest object. The body contains two part viz. Definition and Content from csv. I don't know where i'm stuck and i'm getting an error:- "The remote server returned an error: (400) bad request". I'm able to generate access token successfully using Service Account.

下面是我的code: -

Here is my code:-

        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();

我编辑了code,仍然得到错误400错误的请求: -

I edited the code, still getting error 400 bad request:-

 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(); 

现在,我试图用另一种方式: -

Now, i'm trying it in another way:-

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. 

请帮我无论我是在正确的方向这块code。

please help me out whether i'm going in the right direction with this piece of code.

推荐答案

乍一看,我认为这个问题可能是你似乎是编码整个请求,而不是仅仅是内容本身。我会建议使用如下描述的FileStream类。

At first glance, I think the problem might be that you seem to be encoding the entire request, rather then just the content itself. I would suggest using the FileStream Class as described here.

 
精彩推荐