2014-01-08 13 views
37

WCFサービス(WCFサービスからWCFサービス)からGZipエンコードJSONを返すAPIに接続しようとしています。 HTTPClientを使用してAPIに接続し、JSONオブジェクトを文字列として返すことができました。しかし、私はこの返されたデータをデータベースに格納する必要があります。そのため、JSONオブジェクトを配列やバイト、またはそれらの行に沿ったものに戻して格納するのが最善の方法だと思いました。HTTPClientレスポンスからGZipストリームを解凍する

特に私が問題を抱えているのは、GZipエンコーディングの解凍で、さまざまな例を試していますが、それでもそれを得ることはできません。

以下のコードは、接続を確立して応答を得る方法です。これは、APIから文字列を返すコードです。

public string getData(string foo) 
    { 
     string url = ""; 
     HttpClient client = new HttpClient(); 
     HttpResponseMessage response; 
     string responseJsonContent; 
     try 
     { 
      client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); 
      response = client.GetAsync(url + foo).Result; 
      responseJsonContent = response.Content.ReadAsStringAsync().Result; 
      return responseJsonContent; 
     } 
     catch (Exception ex) 
     { 
      System.Windows.Forms.MessageBox.Show(ex.Message); 
      return ""; 
     } 
    } 

私は、これらのStackExchange APIのようないくつかの異なる例を以下MSDN、およびstackoverflowの上のカップルが、私はこれらのいずれかが私のために働くことを得ることができていないされています。

これを達成する最善の方法は何ですか?適切なトラックにいてもですか?

ありがとうございます。

答えて

93

はちょうどこのようにHttpClientをインスタンス化:

HttpClientHandler handler = new HttpClientHandler() 
{ 
    AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate 
}; 

using (var client = new HttpClient(handler)) 
{ 
    // your code 
} 
+0

この構造を使用すると、httpClientから自分のレスポンスの内容を取得するにはどうすればよいですか?私はC#のスーパーで新しく、私はそれを得ているとは思わない。 – FoxDeploy

+1

@FoxDeployこのソリューションを使用するときに、コードがコンテンツを取得するために必要な変更はありません。参考までここをクリックしてください:https://stackoverflow.com/questions/26597665/how-to-get-content-body-from-a-httpclient-call – DIG

+0

これは古い投稿ですが、この回答は私の問題を解決しました。 。netcore、1.1から2.0に移行すると、クライアントは自動的に解凍を行っていたようですので、このコードを2.0に追加して動作させる必要がありました...ありがとう! –

0

私は最終的に私の問題を解決しました。より良い方法があれば私に教えてください:-)

 public DataSet getData(string strFoo) 
    { 
     string url = "foo"; 

     HttpClient client = new HttpClient(); 
     HttpResponseMessage response; 
     DataSet dsTable = new DataSet(); 
     try 
     { 
       //Gets the headers that should be sent with each request 
      client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); 
       //Returned JSON 
      response = client.GetAsync(url).Result; 
       //converts JSON to string 
      string responseJSONContent = response.Content.ReadAsStringAsync().Result; 
       //deserializes string to list 
      var jsonList = DeSerializeJsonString(responseJSONContent); 
       //converts list to dataset. Bad name I know. 
      dsTable = Foo_ConnectAPI.ExtentsionHelpers.ToDataSet<RootObject>(jsonList); 
       //Returns the dataset     
      return dsTable; 
     } 
     catch (Exception ex) 
     { 
      System.Windows.Forms.MessageBox.Show(ex.Message); 
      return null; 
     } 
    } 

     //deserializes the string to a list. Utilizes JSON.net. RootObject is a class that contains the get and set for the JSON elements 

    public List<RootObject> DeSerializeJsonString(string jsonString) 
    { 
      //Initialized the List 
     List<RootObject> list = new List<RootObject>(); 
      //json.net deserializes string 
     list = (List<RootObject>)JsonConvert.DeserializeObject<List<RootObject>>(jsonString); 

     return list; 
    } 

RootObjectには、JSONの値を取得するget setが含まれています。

public class RootObject 
{ 
     //These string will be set to the elements within the JSON. Each one is directly mapped to the JSON elements. 
     //This only takes into account a JSON that doesn't contain nested arrays 
    public string EntityID { get; set; } 

    public string Address1 { get; set; } 

    public string Address2 { get; set; } 

    public string Address3 { get; set; } 

} 

上記クラス(複数可)を作成する最も簡単な方法は、それに応じてフォーマットするjson2charpを使用しても正しいデータ型を提供することです。

次はもう一度Stackoverflow のネストされたJSONを考慮していません。

internal static class ExtentsionHelpers 
{ 
    public static DataSet ToDataSet<T>(this List<RootObject> list) 
    { 
     try 
     { 
      Type elementType = typeof(RootObject); 
      DataSet ds = new DataSet(); 
      DataTable t = new DataTable(); 
      ds.Tables.Add(t); 

      try 
      { 
       //add a column to table for each public property on T 
       foreach (var propInfo in elementType.GetProperties()) 
       { 
        try 
        { 
         Type ColType = Nullable.GetUnderlyingType(propInfo.PropertyType) ?? propInfo.PropertyType; 

          t.Columns.Add(propInfo.Name, ColType); 

        } 
        catch (Exception ex) 
        { 
         System.Windows.Forms.MessageBox.Show(ex.Message); 
        } 

       } 
      } 
      catch (Exception ex) 
      { 
       System.Windows.Forms.MessageBox.Show(ex.Message); 
      } 

      try 
      { 
       //go through each property on T and add each value to the table 
       foreach (RootObject item in list) 
       { 
        DataRow row = t.NewRow(); 

        foreach (var propInfo in elementType.GetProperties()) 
        { 
         row[propInfo.Name] = propInfo.GetValue(item, null) ?? DBNull.Value; 
        } 

        t.Rows.Add(row); 
       } 
      } 
      catch (Exception ex) 
      { 
       System.Windows.Forms.MessageBox.Show(ex.Message); 
      } 

      insert.insertCategories(t); 
      return ds. 
     } 
     catch (Exception ex) 
     { 
      System.Windows.Forms.MessageBox.Show(ex.Message); 

      return null; 
     } 
    } 
}; 

は、その後最終的に私はSQLの一括コピーからJSONを挿入するための次のクラスしたがって、上記の作品

public class insert 
{ 
    public static string insertCategories(DataTable table) 
    {  
     SqlConnection objConnection = new SqlConnection(); 
      //As specified in the App.config/web.config file 
     objConnection.ConnectionString = System.Configuration.ConfigurationManager.ConnectionStrings["foo"].ToString(); 

     try 
     {         
      objConnection.Open(); 
      var bulkCopy = new SqlBulkCopy(objConnection.ConnectionString); 

      bulkCopy.DestinationTableName = "dbo.foo"; 
      bulkCopy.BulkCopyTimeout = 600; 
      bulkCopy.WriteToServer(table); 

      return ""; 
     } 
     catch (Exception ex) 
     { 
      System.Windows.Forms.MessageBox.Show(ex.Message); 
      return ""; 
     } 
     finally 
     { 
      objConnection.Close(); 
     }   
    } 
}; 

を利用JSONにマッピングされた列を持つテーブルに上記のデータセットを挿入しますwebAPIをデータベースに追加します。これは私が仕事に就くものです。しかし、決して完璧であるとは思っていません。改善があればそれに応じて更新してください。

+1

あなたは基礎となるストリームの適切な、タイムリーな処分や閉鎖を確実にするために、 '使用して()'ステートメントそれぞれの内部で、あなたの 'HttpClient'とあなたの' HttpResponse'を作成する必要があります。 –

関連する問題