5

我的应用程序需要(几乎是默认的)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 吗?

4

3 回答 3

8

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

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"
    };
}
于 2019-05-14T10:05:03.970 回答
1

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

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() });
    }

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

于 2019-05-14T10:02:13.863 回答
1

只需Json()在您的控制器中覆盖

public class MyController : Controller
{
    public override JsonResult Json(object data)
    {
        return base.Json(data, new JsonSerializerSettings {
            // set whataever options you want
        });
    }
}
于 2021-09-12T22:07:37.187 回答