.net 使用HttpWebRequest POST方法将本地CSV文件数据导入大查询表
我正在尝试创建一个新的作业主体,并使用HttpWebRequest对象将此主体发布到BigQuery。 正文包括两部分,即:。csv的定义和内容。我不知道我在哪里卡住了,我得到了一个错误:-“远程服务器返回了一个错误:(400)错误请求”。 我能够使用服务帐户成功生成访问令牌 这是我的密码:-.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
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类