2014-01-08 3 views
37

Я пытаюсь подключиться к api, который возвращает JSON, закодированный GZip, из службы WCF (служба WCF для службы WCF). Я использую HTTP-клиент для подключения к API и смог вернуть объект JSON в виде строки. Однако мне нужно иметь возможность хранить эти возвращенные данные в базе данных, и поэтому я решил, что лучший способ - вернуть и сохранить объект JSON в массиве или байте или что-то в этом направлении.Декомпрессию потока GZip из HTTPClient Response

У меня возникли проблемы с конкретным декомпрессией кодировки 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.

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; 
     } 
    } 
}; 

Тогда, наконец, вставить указанный выше набор данных в таблицу со столбцами, которые были нанесены на карту в формате JSON я использовал SQL массового копирования и следующий класс

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' внутри 'используя()' оператор каждого, чтобы обеспечить надлежащее, своевременное удаление и закрытие основных потоков. –

Смежные вопросы