如何使用自定义格式化程序进行json序列化

时间:2016-10-06 09:27:40

标签: asp.net asp.net-web-api

在下面的代码中,我手动创建一个符合我们的标准json响应对象格式的json对象,这对于错误和实际响应都是相同的:

{ data : { /*something*/ }, status : { httpCode : 123, message: "error message" } }

如何配置ASP.NET为我执行此格式化?在进行内容协商时,使用标准JSON and XML formatter显然可以这样做,但链接的文章只指向page on Custom Formatters是空白的(也适用于我没有使用的ASP.NET MVC)...

我还希望它能够在响应对象中设置返回的http代码(如下所示)。

当前手动格式化json

[StandardizedRestServiceExceptionFilter]
public class FooController : ApiController
{
    /// <summary>
    /// 
    /// The return format for both real results and errors
    /// is { data : { }, status : { httpCode : 123, message: "error message" }
    ///
    /// We have moved the error serialization to StandardizedRestServiceExceptionFilter,
    /// but was unable to generalize the processing of the output format for normal responses
    /// That could be improved, possibly using a IMessageFormatter ?
    /// </summary>
    /// <param name="code"></param>
    /// <returns></returns
    [HttpGet]
    public JObject Coverage(string code)
    {
        dynamic returnObject = new JObject();
        dynamic statusObject = new JObject();
        dynamic dataObject = new JObject();

        JArray stores = StoresWithCoverage(code);
        var hasCoverage = stores.Count > 0;
        dataObject.coverage = hasCoverage;

        returnObject.data = dataObject;
        returnObject.status = statusObject;

        statusObject.message = "";
        statusObject.httpCode = 200;

        return returnObject;
        }
    }
}

因此,在上面的示例中,我希望能够返回具有coverage属性的某种Object,并让ASP.NET对JSON进行实际格式化和序列化(如果在内容协商中请求) )。

1 个答案:

答案 0 :(得分:1)

可以使用ASP.NET Web API使用预构建或自定义Media Formatters

在这种情况下,可以从上面的链接中获取自定义格式化程序作为示例,并根据需要修改JSON内容包装器(此处:使用JSON.NET):

首先,您需要指定支持的内容类型:

public CustomJsonFormatter()
{
    // Add the supported media type.
    SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/json"));
}

然后,您需要实现覆盖WriteToStream方法:

public override void WriteToStream(Type type, object value, Stream  writeStream, HttpContent content)
{
    using (var writer = new StreamWriter(writeStream, effectiveEncoding))
    {
        using (JsonWriter jw = new JsonTextWriter(writer))
        {
            dynamic returnObject = new JObject();
            dynamic status = new JObject();
            JObject data = (JObject)JToken.FromObject(value);

            status.httpCode = HttpContext.Current.HttpResponse.StatusCode;
            status.message = null;

            returnObject.data = data;
            returnObject.status = status;

            jw.Formatting = Formatting.Indented;

            JsonSerializer serializer = new JsonSerializer();
            // for customizing settings, like lower casing
            // attribute names, see http://stackoverflow.com/a/6288726/200987
            serializer.ContractResolver = new CamelCasePropertyNamesContractResolver()

            serializer.Serialize(jw, returnObject);
        }
    }
}

最后需要说明哪种类型支持转换,使用ASP.NET注册此格式化程序,以及其他一些次要(通常是非必需的)修改。请参阅以下文章,了解如何执行此操作,以及序列化,http状态代码和内容协商的工作方式以及可自定义。