.net 使用HttpWebRequest POST方法将本地CSV文件数据导入大查询表

.net 使用HttpWebRequest POST方法将本地CSV文件数据导入大查询表,.net,google-bigquery,.net,Google Bigquery,我正在尝试创建一个新的作业主体,并使用HttpWebRequest对象将此主体发布到BigQuery。 正文包括两部分,即:。csv的定义和内容。我不知道我在哪里卡住了,我得到了一个错误:-“远程服务器返回了一个错误:(400)错误请求”。 我能够使用服务帐户成功生成访问令牌 这是我的密码:- string strURL = "https://www.googleapis.com/upload/bigquery/v2/projects/" + strProjId + "/jobs

我正在尝试创建一个新的作业主体,并使用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. 
内部类clsGetOAuth2Authentication
{
公共OAuth2Authenticator objGetOAuth2(字符串strPrivateFilePath、字符串strPrivateFilePassword、字符串strServiceAccEmailId、字符串strScope)
{
授权服务器描述objAuthServerDesc;
X509E2-objKey;
断言FlowClient对象客户端;
OAuth2Authenticator objAuth=null;
字符串范围URL=”https://www.googleapis.com/auth/“+strScope;
string strSrvAccEmailId=strServiceAccEmailId;//strSrvAccEmailId:这是服务帐户的电子邮件地址。
string strKeyFile=strPrivateFilePath;//KeyFile:这是创建服务帐户时下载的密钥文件的物理路径。
字符串strKeyPassword=(strPrivateFilePassword!=“”)?strPrivateFilePassword:“notasecret”//key\u pass:这可能是所有密钥文件的密码,但如果您获得了不同的密码,请使用它。
objAuthServerDesc=GoogleAuthenticationServer.Description;//objAuthServerDesc:将授予身份验证的服务器的描述。
objKey=newx509certificate2(strKeyFile,strKeyPassword,x509keystrageflags.Exportable);//objKey:加载并解密密钥。
objClient=new AssertionFlowClient(objAuthServerDesc,objKey){ServiceAccountId=strSrvAccEmailId,Scope=ScopeUrl};//objClient:使用AssertionFlowClient,因为我们使用证书登录。
objAuth=新的OAuth2Authenticator(objClient,AssertionFlowClient.GetState);//objAuth:请求身份验证。
返回objAuth;
}
}
//上述类返回OAuth2Authenticator对象:-
clsGetOAuth2Authentication objOAuth2=新的clsGetOAuth2Authentication();
var objAuth=objOAuth2.objGetOAuth2(strKeyFile、strKeyPassword、strrsrvaccemailid、strScope)//返回的身份验证数据
objBQServ=新的BigqueryService(objAuth)//使用授权实例化BigQueryService
TableReference objTblRef=新的TableReference();
objTblRef.ProjectId=strProjId;
objTblRef.DatasetId=strDatasetId;
objTblRef.TableId=“tblEvents”;
JobConfigurationLoad objJobConfigLoad=新JobConfigurationLoad();
objJobConfigLoad.FieldDelimiter=“|”;
objJobConfigLoad.DestinationTable=objTblRef;
objJobConfigLoad.WriteDisposition=“WRITE\u APPEND”;
JobConfiguration objJobConfig=newjobconfiguration(){Load=objjobconfiguload};
Job objJob=newjob(){Configuration=objJobConfig,Kind=“bigquery#jobs”,Id=“TestJob”};
FileStream objFS=newfilestream(“D:\\tblEvents2.csv”,FileMode.Open,FileAccess.Read);
byte[]objFileData=新字节[objFS.Length];
读取(objFileData,0,objFileData.Length);
objFS.Close();
Stream objDataStream=新内存流();
写入(objFileData,0,objFileData.Length);
Insert(objJob,strProjId,objDataStream,“application/octet stream”).Upload()//在Upload()方法中获取错误。对象无法初始化。

请帮助我确定我使用这段代码的方向是否正确。

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