如何为“自定义”JsonDotNetResult提供可选设置?

时间:2016-05-23 08:42:30

标签: asp.net json asp.net-mvc asp.net-mvc-5

我有一个替代JsonResult,作为下面的类,提供比MVC Web Apps的默认值更好的JSON序列化器(省略不相关的位):

public class JsonDotNetResult : JsonResult
{
    public readonly JsonSerializerSettings Settings = new JsonSerializerSettings
    {
        PreserveReferencesHandling = PreserveReferencesHandling.Arrays,
        ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
        ContractResolver = new CamelCasePropertyNamesContractResolver(),
        Converters = new List<JsonConverter> { new StringEnumConverter() }
    };

    public override void ExecuteResult(ControllerContext context)
    {
        ...
        var response = context.HttpContext.Response;
        ...
        response.Write(JsonConvert.SerializeObject(Data, Settings));
    }
}

然后我有Controller.Json的重载,声明为:

protected JsonResult Json(object data, string contentType, Encoding contentEncoding, JsonRequestBehavior behavior, JsonSerializerSettings settings = null)

但我没有在Settings的{​​{1}}字段中设置现有的默认设置,因此如果我传入新的JsonDotNetResult,并且调用者设置了一些属性,我将使用JsonSerializerSettings的默认值以及调用者提供的新值覆盖Settings对象的所有属性。后者是理想的,前者我试图避免。

如何传递JsonSerializerSettings属性值的子集并将其应用于JsonSerializerSettings中的Settings对象?我最好的(也是第一次)努力是遍历默认JsonDotNetResult对象的属性,并将它们与用户传递的新Settings对象的属性值进行比较,如果不同,则设置值在JsonSerializerSettings上,用户提供的值。

1 个答案:

答案 0 :(得分:1)

我将在Global.asax.cs中为JsonConvert定义全局默认设置:

protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();
    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    RouteConfig.RegisterRoutes(RouteTable.Routes);
    BundleConfig.RegisterBundles(BundleTable.Bundles);

    JsonConvert.DefaultSettings = () => new JsonSerializerSettings
    {
        PreserveReferencesHandling = PreserveReferencesHandling.Arrays,
        ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
        ContractResolver = new CamelCasePropertyNamesContractResolver(),
        Converters = new List<JsonConverter> { new StringEnumConverter() }
    };
}

JsonConvert.DefaultSettings是一个lambda函数,用于创建转换器使用的默认设置。当您提供自己的设置时,将覆盖默认设置。那么,每当你想改变那些设置时,只需要调用

var settings = (JsonSerializerSettings)JsonConvert.DefaultSettings.Invoke();

获取您可以根据需要修改的默认设置的新副本。

settings.ReferenceLoopHandling = ReferenceLoopHandling.Serialize;

这样你可以从JsonDotNetResult中删除readonly JsonSerializerSettings Settings = new JsonSerializerSettings,因为它无论如何都会使用默认设置:

public class JsonDotNetResult : JsonResult
{
    public override void ExecuteResult(ControllerContext context)
    {
        ...
        var response = context.HttpContext.Response;
        ...
        response.Write(JsonConvert.SerializeObject(Data));
    }
}

我喜欢这种方法的方法是在一个地方使用默认设置,这样可以保持代码清洁,易于维护。