我正在尝试创建一个新的作业正文并使用 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.
请帮我看看这段代码我是否朝着正确的方向前进。