HTTPClient 응답에서 GZip 스트림 압축 해제
WCF 서비스 (WCF 서비스에서 WCF 서비스로)에서 GZip으로 인코딩 된 JSON을 반환하는 API에 연결하려고합니다. 내가 사용하고 HttpClient를 API를 연결하고 문자열로 JSON 개체를 반환 할 수 있었다. 그러나이 반환 된 데이터를 데이터베이스에 저장할 수 있어야하므로 가장 좋은 방법은 JSON 개체를 배열이나 바이트 또는 해당 줄을 따라 저장하는 것입니다.
내가 특히 문제가있는 것은 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와 같은 몇 가지 다른 예제를 따라 왔지만 이러한 예제 중 어느 것도 나를 위해 작동하지 못했습니다.
이를 수행하는 가장 좋은 방법은 무엇입니까? 나는 올바른 길을 가고 있습니까?
감사합니다.
다음과 같이 HttpClient를 인스턴스화하십시오.
HttpClientHandler handler = new HttpClientHandler()
{
AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate
};
using (var client = new HttpClient(handler))
{
// your code
}
그래서 결국 내 문제를 해결했습니다. 더 좋은 방법이 있으면 알려주세요 :-)
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 집합이 포함되어 있습니다.
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;
}
}
};
Then finally to insert the above dataset into a table with columns that were mapped to the JSON I utilized SQL bulk copy and the following class
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();
}
}
};
So the above works to insert JSON from a webAPI into a database. This is something that I get to work. But by no means do I expect it to be perfect. If you have any improvements then please update it accordingly.
I used code from below link to decompress GZip stream.Then used the decompressed byte array to get the required JSON object. Hope it may help some one.
https://www.dotnetperls.com/decompress
var readTask = result.Content.ReadAsByteArrayAsync().Result;
var decompressedData = Decompress(readTask);
string jsonString = System.Text.Encoding.UTF8.GetString(decompressedData, 0, decompressedData.Length);
ResponseObjectClass responseObject = Newtonsoft.Json.JsonConvert.DeserializeObject<ResponseObjectClass>(jsonString);
참고URL : https://stackoverflow.com/questions/20990601/decompressing-gzip-stream-from-httpclient-response
'IT TIP' 카테고리의 다른 글
const 객체를 반환해야합니까? (0) | 2020.10.15 |
---|---|
업데이트 된 APK를 수동으로 설치하면 '서명이 이전에 설치된 버전과 일치하지 않습니다.'와 함께 실패합니다. (0) | 2020.10.15 |
선택기 'my-app'이 어떤 요소와도 일치하지 않습니다. (0) | 2020.10.15 |
파일을 업로드하기위한 fileReader.readAsBinaryString (0) | 2020.10.15 |
ListView WPF의 헤더를 어떻게 숨길 수 있습니까? (0) | 2020.10.15 |