将 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。不需要任何高级序列化和格式化。此处有更多信息。

https://msdn.microsoft.com/en-us/library/system.net.http.httprequestmessageextensions.createresponse%28v=vs.118%29.aspx

Request.CreateResponse(HttpStatusCode.InternalServerError, new string[] { "value1", "value2" }, new JsonMediaTypeFormatter())

(或)

Request.CreateResponse(HttpStatusCode.InternalServerError, new string[] { "value1", "value2" }, 'application/json')