将 JsonContent 在 Web Api 中使用 Json.NET 多次序列化 2
Will JsonContent get serialised multiple times using Json.NET in Web Api 2
如果我有这个控制器:
public class SomeController : ApiController
{
public SomeInfoDto Get()
{
return new SomeInfoDto();
}
}
当我用获取请求调用 /api/Some
时,我将在内容正文中得到 JSON
,因为 JSON.NET 已经很友好地为我序列化它。
但是,如果我想发送 500
HTTP 代码和一些 JSON
我想我可以这样做:
public HttpResponseMessage Get()
{
return new HttpResponseMessage(HttpStatusCode.InternalServerError)
{
Content = // not sure what to put here
}
}
所以我在 google 上搜索了 Content
的内容,然后找到了这个 resource
public class JsonContent : HttpContent
{
private readonly JToken _value;
public JsonContent(JToken value)
{
_value = value;
Headers.ContentType = new MediaTypeHeaderValue("application/json");
}
protected override Task SerializeToStreamAsync(Stream stream,
TransportContext context)
{
var jw = new JsonTextWriter(new StreamWriter(stream))
{
Formatting = Formatting.Indented
};
_value.WriteTo(jw);
jw.Flush();
return Task.FromResult<object>(null);
}
protected override bool TryComputeLength(out long length)
{
length = -1;
return false;
}
}
我可以轻松修改以适合我的目的。
但是,我的问题是,如果我让 SerializeToStreamAsync
在 Web Api 管道的更下方使用 JsonConvert.SerializeObject(_value)
,它会再次被序列化吗?
我这样设置 GlobalConfiguration.Configuration
:
var formatters = GlobalConfiguration.Configuration.Formatters;
var jsonFormatter = formatters.JsonFormatter;
var settings = jsonFormatter.SerializerSettings;
settings.Formatting = Formatting.Indented;
settings.ContractResolver = new CamelCasePropertyNamesContractResolver();
我对 SerializeToStreamAsync
的实现是这样的:
protected override Task SerializeToStreamAsync(Stream stream, TransportContext context)
{
using (var streamWriter = new StreamWriter(stream))
{
streamWriter.WriteAsync(JsonConvert.SerializeObject(this.value)).Wait();
streamWriter.FlushAsync().Wait();
}
return Task.FromResult<object>(null);
}
编辑:提供带有格式化程序的具体示例。
如果你想发送JSON个Http Status Code 500的内容,你可以使用扩展方法HttpRequestMessage.CreateResponse。不需要任何高级序列化和格式化。此处有更多信息。
Request.CreateResponse(HttpStatusCode.InternalServerError, new string[] { "value1", "value2" }, new JsonMediaTypeFormatter())
(或)
Request.CreateResponse(HttpStatusCode.InternalServerError, new string[] { "value1", "value2" }, 'application/json')
如果我有这个控制器:
public class SomeController : ApiController
{
public SomeInfoDto Get()
{
return new SomeInfoDto();
}
}
当我用获取请求调用 /api/Some
时,我将在内容正文中得到 JSON
,因为 JSON.NET 已经很友好地为我序列化它。
但是,如果我想发送 500
HTTP 代码和一些 JSON
我想我可以这样做:
public HttpResponseMessage Get()
{
return new HttpResponseMessage(HttpStatusCode.InternalServerError)
{
Content = // not sure what to put here
}
}
所以我在 google 上搜索了 Content
的内容,然后找到了这个 resource
public class JsonContent : HttpContent
{
private readonly JToken _value;
public JsonContent(JToken value)
{
_value = value;
Headers.ContentType = new MediaTypeHeaderValue("application/json");
}
protected override Task SerializeToStreamAsync(Stream stream,
TransportContext context)
{
var jw = new JsonTextWriter(new StreamWriter(stream))
{
Formatting = Formatting.Indented
};
_value.WriteTo(jw);
jw.Flush();
return Task.FromResult<object>(null);
}
protected override bool TryComputeLength(out long length)
{
length = -1;
return false;
}
}
我可以轻松修改以适合我的目的。
但是,我的问题是,如果我让 SerializeToStreamAsync
在 Web Api 管道的更下方使用 JsonConvert.SerializeObject(_value)
,它会再次被序列化吗?
我这样设置 GlobalConfiguration.Configuration
:
var formatters = GlobalConfiguration.Configuration.Formatters;
var jsonFormatter = formatters.JsonFormatter;
var settings = jsonFormatter.SerializerSettings;
settings.Formatting = Formatting.Indented;
settings.ContractResolver = new CamelCasePropertyNamesContractResolver();
我对 SerializeToStreamAsync
的实现是这样的:
protected override Task SerializeToStreamAsync(Stream stream, TransportContext context)
{
using (var streamWriter = new StreamWriter(stream))
{
streamWriter.WriteAsync(JsonConvert.SerializeObject(this.value)).Wait();
streamWriter.FlushAsync().Wait();
}
return Task.FromResult<object>(null);
}
编辑:提供带有格式化程序的具体示例。 如果你想发送JSON个Http Status Code 500的内容,你可以使用扩展方法HttpRequestMessage.CreateResponse。不需要任何高级序列化和格式化。此处有更多信息。
Request.CreateResponse(HttpStatusCode.InternalServerError, new string[] { "value1", "value2" }, new JsonMediaTypeFormatter())
(或)
Request.CreateResponse(HttpStatusCode.InternalServerError, new string[] { "value1", "value2" }, 'application/json')