AspNet Core - input/output JSON 控制器级别的序列化设置
AspNet Core - input/output JSON serialization settings at Controller Level
我的应用程序需要(几乎是默认的)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();
我的问题几乎与 相同,除了我要求 AspNet Core 2.2+,其中 IControllerConfiguration
不再存在。
Core 2.1+ 等效问题在此处有回复:
那里的答案似乎有些支离破碎或不完整 - 很难想象没有更简单的方法可以做到这一点。
有人知道如何在单个控制器中对所有输入和输出使用 DefaultContractResolver 吗?
对于 Startup.cs 中的全局设置,安装 Newtonsoft.json 后,您将拥有此
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
.AddJsonOptions(options => options.SerializerSettings.ContractResolver = new DefaultContractResolver());
对于 Individual Controller,您可以覆盖下面的全局设置
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() });
}
如果这能解决您的问题,或者您需要进一步的帮助,请告诉我。
您 link 的回答效果很好,但您可以通过将其包装在可应用于任何操作或控制器的属性中来进一步扩展它。例如:
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"
};
}
只需在您的控制器中覆盖 Json()
public class MyController : Controller
{
public override JsonResult Json(object data)
{
return base.Json(data, new JsonSerializerSettings {
// set whataever options you want
});
}
}
我的应用程序需要(几乎是默认的)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();
我的问题几乎与 IControllerConfiguration
不再存在。
Core 2.1+ 等效问题在此处有回复:
那里的答案似乎有些支离破碎或不完整 - 很难想象没有更简单的方法可以做到这一点。 有人知道如何在单个控制器中对所有输入和输出使用 DefaultContractResolver 吗?
对于 Startup.cs 中的全局设置,安装 Newtonsoft.json 后,您将拥有此
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
.AddJsonOptions(options => options.SerializerSettings.ContractResolver = new DefaultContractResolver());
对于 Individual Controller,您可以覆盖下面的全局设置
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() });
}
如果这能解决您的问题,或者您需要进一步的帮助,请告诉我。
您 link 的回答效果很好,但您可以通过将其包装在可应用于任何操作或控制器的属性中来进一步扩展它。例如:
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"
};
}
只需在您的控制器中覆盖 Json()
public class MyController : Controller
{
public override JsonResult Json(object data)
{
return base.Json(data, new JsonSerializerSettings {
// set whataever options you want
});
}
}