一尘不染

MVC 4中正确的JSON序列化

c#

我想对JSON进行“正确”序列化(camelCase),并在需要时能够更改日期格式。

对于Web API,这非常简单-在Global.asax中,我执行以下代码

var json = GlobalConfiguration.Configuration.Formatters.JsonFormatter;
json.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();

该代码在管道级别上以我想要的方式处理序列化。

我想在MVC 4中完成相同的操作-从控制器操作方法返回的任何JSON都要正确序列化。稍作搜索,我发现以下代码将引发Global.asax应用程序启动:

HttpConfiguration config = GlobalConfiguration.Configuration;
Int32 index = config.Formatters.IndexOf(config.Formatters.JsonFormatter);
config.Formatters[index] = new JsonMediaTypeFormatter
{
     SerializerSettings = new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() }
};

似乎执行得很好,但是当我从控制器返回JSON时,全部都是PascalCased。我的操作方法的一个简单示例:

private JsonResult GetJsonTest()
{
    var returnData = dataLayer.GetSomeObject();
    return Json(returnData, JsonRequestBehavior.AllowGet);
}

我要解决这个错误吗?知道如何在管道级别上做到这一点吗?


阅读 412

收藏
2020-05-19

共1个答案

一尘不染

我建议使用诸如ServiceStack或Json.NET之类的东西来处理MVC应用程序中的Json输出。但是,您可以轻松地编写一个类,并使用基类覆盖Json方法。请参阅下面的示例。

注意:这样,您在Global.ascx.cs文件中不需要任何内容​​。

自定义JsonDotNetResult类:

public class JsonDotNetResult : JsonResult
{
    private static readonly JsonSerializerSettings Settings = new JsonSerializerSettings
    {
        ContractResolver = new CamelCasePropertyNamesContractResolver(),
        Converters = new List<JsonConverter> { new StringEnumConverter() }
    };

    public override void ExecuteResult(ControllerContext context)
    {
        if (this.JsonRequestBehavior == JsonRequestBehavior.DenyGet &&
            string.Equals(context.HttpContext.Request.HttpMethod, "GET", StringComparison.OrdinalIgnoreCase))
        {
            throw new InvalidOperationException("GET request not allowed");
        }

        var response = context.HttpContext.Response;

        response.ContentType = !string.IsNullOrEmpty(this.ContentType) ? this.ContentType : "application/json";

        if (this.ContentEncoding != null)
        {
            response.ContentEncoding = this.ContentEncoding;
        }

        if (this.Data == null)
        {
            return;
        }

        response.Write(JsonConvert.SerializeObject(this.Data, Settings));
    }
}

基本控制器类:

public abstract class Controller : System.Web.Mvc.Controller
{
    protected override JsonResult Json(object data, string contentType, System.Text.Encoding contentEncoding, JsonRequestBehavior behavior)
    {
        return new JsonDotNetResult
            {
                Data = data,
                ContentType = contentType,
                ContentEncoding = contentEncoding,
                JsonRequestBehavior = behavior
            };
    }
}

现在,在控制器操作上,您只需返回类似的内容即可。

return Json(myObject, JsonRequestBehavior.AllowGet);

BAM。现在,您有了Json返回的驼峰对象:)

注意:有多种方法可以使用Json制作的每个对象上的Serializer设置进行操作。但是,每当您想返回Json时,谁愿意输入该信息?

2020-05-19