我必须使用哪种表达方式?或者将StreamContent与JsonTextWriter一起使用
本文关键字:StreamContent 一起 或者 JsonTextWriter 表达方式 | 更新日期: 2023-09-27 18:27:30
我正在用.NET Framework 4.5、C#和Newtonsoft.Json 6.0.8开发一个ASP.NET Web Api 2.2应用程序。
我有这个方法发布到这个网络api:
protected bool Post<T>(string completeUri, ref T dataToPost)
{
bool result = false;
using (var client = new HttpClient())
{
client.BaseAddress = new Uri(_webApiHost);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpContent content = new StringContent(JsonConvert.SerializeObject(dataToPost), Encoding.UTF8, "application/json");
Task<HttpResponseMessage> response = client.PostAsync(completeUri, content);
[ ... ]
}
return result;
}
当我有很多数据要发送时,我会在这里得到内存不足的异常:
HttpContent content = new StringContent(JsonConvert.SerializeObject(dataToPost), Encoding.UTF8, "application/json");
我读了很多关于压缩的书,但我不知道该用哪一本。我不知道是否还有更多的类型,但我发现了两种:IIS压缩和GZip压缩。
我必须用哪一个?如果我使用GZip压缩,我是否必须修改我的web api客户端?
更新:
我有这个类要序列化,但我还没有使用它:
public static string Serialize(Models.Aggregations aggregation)
{
if (aggregation == null)
throw new ArgumentNullException("aggregation");
StringWriter sw = new StringWriter();
JsonTextWriter writer = new JsonTextWriter(sw);
writer.WriteStartObject();
writer.WritePropertyName("Code");
writer.WriteValue(aggregation.Code);
if (!string.IsNullOrWhiteSpace(aggregation.Created))
{
writer.WritePropertyName("Created");
writer.WriteValue(aggregation.Created);
}
writer.WriteEndObject();
return sw.ToString();
}
如果我使用它,它会解决问题吗?我问这个问题是因为@CodeCaster建议我使用JsonTextWriter
,但我不知道如何在我的post方法中使用它。
更新2
根据@CodeCaster的建议,我正在努力优化向该Web Api发送数据的方式,我正在用这个类编写自己的JSON序列化程序:
public static string Serialize(Models.Aggregations aggregation)
{
if (aggregation == null)
throw new ArgumentNullException("aggregation");
StringWriter sw = new StringWriter();
JsonTextWriter writer = new JsonTextWriter(sw);
writer.WriteStartObject();
writer.WritePropertyName("Code");
writer.WriteValue(aggregation.Code);
if (!string.IsNullOrWhiteSpace(aggregation.Created))
{
writer.WritePropertyName("Created");
writer.WriteValue(aggregation.Created);
}
writer.WriteEndObject();
return sw.ToString();
}
但@CodeCaster告诉我,为了提高效率,我需要使用JsonTextWriter
将其作为流写入StreamContent
。
但我不知道该怎么做,因为我不知道如何实例化StreamContent
。我看到的所有示例都使用var stream
,但我不知道它们是如何实例化该对象的。
如何使用JsonTextWriter写入流?
您所说的压缩不会解决您的问题。
它只会在HTTP级别压缩数据。因此,在您的代码中,您仍然会得到相同的解压缩字符串,以及在反序列化过程中发生的相同OutOfMemoryException
。
您需要更改反序列化JSON的方式。请参阅C#中的增量JSON解析。
编辑:对不起,我读错了。这是序列化,而不是反序列化。不过,同样的问题。序列化本身或StringContent
的实例化都会引发此异常。您需要将其序列化为流式传输,并直接流式传输到输出。
所以:使用StreamContent
,而不是StringContent
,并使用JsonTextWriter
写入流。这样就不必在内存中保存整个序列化字符串。
给定results
作为包含对象的IEnumerable<T>
,您可以使用JsonTextWriter以以下方式写入响应OutputStream:
// get the response output stream ..
using (StreamWriter stream = new StreamWriter(HttpContext.Current.Response.OutputStream))
using (JsonTextWriter writer = new JsonTextWriter(stream))
{
// .. and use json.net to write the data as json in the stream
var serializer = new JsonSerializer();
serializer.Serialize(writer, results);
}
如果你有自己的JsonSerializer
,你可以很容易地将其插入。
响应内容将被压缩和分块。快速整洁的
Response Headers
Transfer-Encoding: chunked
Content-Type: application/json
Content-Encoding: gzip