AspNet Core-控制器级别的输入/输出JSON序列化设置

时间:2019-05-14 09:47:41

标签: c# asp.net-core json-serialization

我的应用程序需要(几乎是默认的)JSON序列化设置:

services.AddMvc()
            .SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
            .AddJsonOptions(options =>
            {
                options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
                options.SerializerSettings.DateFormatHandling = DateFormatHandling.MicrosoftDateFormat;
                options.SerializerSettings.DateTimeZoneHandling = DateTimeZoneHandling.Local;
            });

仅对于一个控制器,我需要对输入(对[FromBody] myComplexObject使用模型绑定,对

使用输出)使用不同的命名策略。
options.SerializerSettings.ContractResolver = new DefaultContractResolver();

我的问题实际上与Web API: Configure JSON serializer settings on action or controller level相同,只是我要的是AspNet Core 2.2+,其中IControllerConfiguration不再存在。

与Core 2.1+相当的问题在这里得到答复:Configure input/output formatters on controllers with ASP.NET Core 2.1

那里的答案似乎有些零散或不完整-很难想象没有比这更简单的方法了。 有人会对如何在单个控制器中的所有输入和输出中使用DefaultContractResolver产生想法吗?

2 个答案:

答案 0 :(得分:3)

您链接的答案效果很好,但是您可以通过将其包装在可应用于任何操作或控制器的属性中来进一步扩展它。例如:

public class JsonConfigFilterAttribute : ActionFilterAttribute
{
    public override void OnResultExecuting(ResultExecutingContext context)
    {
        if (context.Result is ObjectResult objectResult)
        {
            var serializerSettings = new JsonSerializerSettings
            {
                ContractResolver = new DefaultContractResolver()
            };

            var jsonFormatter = new JsonOutputFormatter(
                serializerSettings, 
                ArrayPool<char>.Shared);

            objectResult.Formatters.Add(jsonFormatter);
        }

        base.OnResultExecuting(context);
    }
}

然后将其添加到动作方法或控制器中

[JsonConfigFilter]
public ActionResult<Foo> SomeAction()
{
    return new Foo
    {
        Bar = "hello"
    };
}

答案 1 :(得分:0)

对于安装了Newtonsoft.json的Startup.cs中的全局设置,您将拥有此

services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
            .AddJsonOptions(options => options.SerializerSettings.ContractResolver = new DefaultContractResolver());

对于单个控制器,您可以覆盖下面的全局设置

 public JsonResult GetStates()
    {
        var model = new List<StateObject>();
        if (!string.IsNullOrEmpty(id))
        {
            var schedule = _settingsService.GetStates().ToList();
            return Json(new SelectList(schedule, "StateCode", "Name"), new JsonSerializerSettings() { ContractResolver = new CamelCasePropertyNamesContractResolver() });
        }
        else
            return Json(new SelectList(model, "StateCode", "Name"), new JsonSerializerSettings() { ContractResolver = new CamelCasePropertyNamesContractResolver() });
    }

让我知道这是否可以解决您的问题,或者您需要进一步的协助。