Descomprimir GZip Stream de HTTPClient Response

Estoy intentando conectarme a una API, que devuelve JSON codificado con GZip, desde un servicio WCF (servicio WCF a servicio WCF). Estoy usando HTTPClient para conectarme a la API y he podido devolver el objeto JSON como una cadena. Sin embargo, necesito poder almacenar estos datos devueltos en una base de datos y, como tal, pensé que la mejor manera sería devolver y almacenar el objeto JSON en una matriz o un byte o algo así.

Lo que estoy teniendo problemas específicamente es la descompresión de la encoding GZip y he estado probando muchos ejemplos diferentes pero todavía no puedo obtenerlo.

El siguiente código es cómo estoy estableciendo mi conexión y obteniendo una respuesta, este es el código que devuelve una cadena de la 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 ""; } } 

He estado siguiendo algunos ejemplos diferentes como StackExchange API , MSDN y un par de stackoverflow, pero no he podido hacer que ninguno de estos funcione para mí.

¿Cuál es la mejor manera de lograr esto, incluso estoy en el camino correcto?

Gracias chicos.

Simplemente crea una instancia de HttpClient así:

 HttpClientHandler handler = new HttpClientHandler() { AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate }; using (var client = new HttpClient(handler)) { // your code } 

Ok, finalmente resolví mi problema. Si hay formas mejores, por favor avíseme 🙂

  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(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 DeSerializeJsonString(string jsonString) { //Initialized the List List list = new List(); //json.net deserializes string list = (List)JsonConvert.DeserializeObject>(jsonString); return list; } 

RootObject contiene el conjunto get que obtendrá los valores de 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; } } 

La forma más sencilla de crear la (s) clase (s) anterior (es) es usar json2charp, que lo formateará en consecuencia y también proporcionará los tipos de datos correctos.

Lo siguiente es de otra respuesta en Stackoverflow nuevamente, no tiene en cuenta el JSON nested.

  internal static class ExtentsionHelpers { public static DataSet ToDataSet(this List 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; } } }; 

Luego, finalmente, para insertar el conjunto de datos anterior en una tabla con columnas que se asignaron a JSON utilicé la copia masiva de SQL y la siguiente clase

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

Entonces, lo anterior funciona para insertar JSON desde una API web en una base de datos. Esto es algo que tengo que trabajar. Pero de ninguna manera espero que sea perfecto. Si tiene alguna mejora, por favor, actualice en consecuencia.