2012-11-14 69 views
1

我正在嘗試創建一個新的工作正文,並使用HttpWebRequest對象將此正文發佈到BigQuery。 身體包含兩部分即。 csv的定義和內容。我不知道我在哪裏卡住,我得到一個錯誤: - 「遠程服務器返回錯誤:(400)錯誤的請求」。 我可以使用服務帳戶成功生成訪問令牌。使用HttpWebRequest POST方法將本地CSV文件數據導入Big Query表

這裏是我的代碼: -

 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. 

請幫我看看我是否正在用這段代碼去正確的方向。

回答

0

乍一看,我認爲問題可能在於您似乎在編碼整個請求,而不僅僅是內容本身。我會建議使用FileStream類as described here