Web API 更改 JSON 解析器
Web API change JSON parser
我正在尝试更改我的网络 API 项目中的 JSON 解析器。
我遵循了以下教程:
https://docs.microsoft.com/en-us/aspnet/core/web-api/advanced/custom-formatters?view=aspnetcore-2.2
https://www.youtube.com/watch?v=tNzgXjqqIjI
https://weblog.west-wind.com/posts/2012/Mar/09/Using-an-alternate-JSON-Serializer-in-ASPNET-Web-API
我现在有以下代码:
public class MyJsonFormatter : MediaTypeFormatter
{
public MyJsonFormatter()
{
base.SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/json"));
}
public override Task WriteToStreamAsync(Type type, object value, Stream writeStream, HttpContent content, TransportContext transportContext, CancellationToken cancellationToken)
{
return null;
}
public override Task WriteToStreamAsync(Type type, object value, Stream writeStream, HttpContent content, TransportContext transportContext)
{
return null;
}
public override void SetDefaultContentHeaders(Type type, HttpContentHeaders headers, MediaTypeHeaderValue mediaType)
{
base.SetDefaultContentHeaders(type, headers, mediaType);
}
public override bool CanReadType(Type type)
{
return true;
}
public override bool CanWriteType(Type type)
{
return true;
}
public override MediaTypeFormatter GetPerRequestFormatterInstance(Type type, HttpRequestMessage request, MediaTypeHeaderValue mediaType)
{
return base.GetPerRequestFormatterInstance(type, request, mediaType);
}
public override Task<object> ReadFromStreamAsync(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger)
{
return null;
}
public override Task<object> ReadFromStreamAsync(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger, CancellationToken cancellationToken)
{
return null;
}
public override IRequiredMemberSelector RequiredMemberSelector { get => base.RequiredMemberSelector; set => base.RequiredMemberSelector = value; }
}
public static void Register(HttpConfiguration config)
{
///Other stuff...
GlobalConfiguration.Configuration.Formatters.Clear();
GlobalConfiguration.Configuration.Formatters.Insert(0, new MyJsonFormatter());
}
我的问题是无论我做什么,JSON 都会被解析并且它似乎忽略了我的代码 - 我可以在读取或写入方法中抛出异常但什么也不会发生,断点不会被击中等.
我知道正在添加此格式化程序,因为只有我的 class 中的内容类型是可见的,如果我将 CanReadType
设置为 return false,则不会解析任何内容。
我的问题是,如何让代码执行我的覆盖?
您需要在启动配置中注册格式化程序。
更新格式化程序的注册方式
public static class WebApiConfig {
public static void Register(HttpConfiguration config) {
// Other stuff...
var jsonFormatter = new MyJsonFormatter();
config.Formatters.Clear();
config.Formatters.Insert(0, jsonFormatter);
//...
}
}
确保在启动或启动应用程序的任何地方都遵循建议的语法。
// configure Web Api
GlobalConfiguration.Configure(WebApiConfig.Register);
还有下面文章中提到的内容协商的过程
Supporting only JSON in ASP.NET Web API – the right way
根据您的示例进行调整,它看起来像
public class JsonContentNegotiator : IContentNegotiator {
MediaTypeHeaderValue mediaType = MediaTypeHeaderValue.Parse("application/json;charset=utf-8");
private readonly MyJsonFormatter _jsonFormatter;
public JsonContentNegotiator(MyJsonFormatter formatter) {
_jsonFormatter = formatter;
}
public ContentNegotiationResult Negotiate(Type type, HttpRequestMessage request, IEnumerable<MediaTypeFormatter> formatters) {
var result = new ContentNegotiationResult(_jsonFormatter, mediaType);
return result;
}
}
并针对您的 HttpConfiguration
注册
var jsonFormatter = new MyJsonFormatter();
config.Formatters.Clear();
config.Formatters.Insert(0, jsonFormatter);
//update content negotiation
config.Services.Replace(typeof(IContentNegotiator), new JsonContentNegotiator(jsonFormatter));
最后要注意的一条信息是框架确实将其 JSON 格式与其自身的 JsonMediaTypeFormatter
紧密耦合
/// <summary>
/// Gets the <see cref="MediaTypeFormatter"/> to use for Json.
/// </summary>
public JsonMediaTypeFormatter JsonFormatter
{
get { return Items.OfType<JsonMediaTypeFormatter>().FirstOrDefault(); }
}
因此,取决于有多少管道实际上取决于 JsonMediaTypeFormatter
实例的存在,它可能会影响 JSON 相关格式。
如果这确实是一个问题,那么我的建议是从 JsonMediaTypeFormatter
派生并根据需要覆盖其成员。
public class MyJsonFormatter : JsonMediaTypeFormatter {
//... removed for brevity
}
但这可能会带来自身的问题,具体取决于基数 class 耦合的对象。
我正在尝试更改我的网络 API 项目中的 JSON 解析器。
我遵循了以下教程:
https://docs.microsoft.com/en-us/aspnet/core/web-api/advanced/custom-formatters?view=aspnetcore-2.2
https://www.youtube.com/watch?v=tNzgXjqqIjI
https://weblog.west-wind.com/posts/2012/Mar/09/Using-an-alternate-JSON-Serializer-in-ASPNET-Web-API
我现在有以下代码:
public class MyJsonFormatter : MediaTypeFormatter
{
public MyJsonFormatter()
{
base.SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/json"));
}
public override Task WriteToStreamAsync(Type type, object value, Stream writeStream, HttpContent content, TransportContext transportContext, CancellationToken cancellationToken)
{
return null;
}
public override Task WriteToStreamAsync(Type type, object value, Stream writeStream, HttpContent content, TransportContext transportContext)
{
return null;
}
public override void SetDefaultContentHeaders(Type type, HttpContentHeaders headers, MediaTypeHeaderValue mediaType)
{
base.SetDefaultContentHeaders(type, headers, mediaType);
}
public override bool CanReadType(Type type)
{
return true;
}
public override bool CanWriteType(Type type)
{
return true;
}
public override MediaTypeFormatter GetPerRequestFormatterInstance(Type type, HttpRequestMessage request, MediaTypeHeaderValue mediaType)
{
return base.GetPerRequestFormatterInstance(type, request, mediaType);
}
public override Task<object> ReadFromStreamAsync(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger)
{
return null;
}
public override Task<object> ReadFromStreamAsync(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger, CancellationToken cancellationToken)
{
return null;
}
public override IRequiredMemberSelector RequiredMemberSelector { get => base.RequiredMemberSelector; set => base.RequiredMemberSelector = value; }
}
public static void Register(HttpConfiguration config)
{
///Other stuff...
GlobalConfiguration.Configuration.Formatters.Clear();
GlobalConfiguration.Configuration.Formatters.Insert(0, new MyJsonFormatter());
}
我的问题是无论我做什么,JSON 都会被解析并且它似乎忽略了我的代码 - 我可以在读取或写入方法中抛出异常但什么也不会发生,断点不会被击中等.
我知道正在添加此格式化程序,因为只有我的 class 中的内容类型是可见的,如果我将 CanReadType
设置为 return false,则不会解析任何内容。
我的问题是,如何让代码执行我的覆盖?
您需要在启动配置中注册格式化程序。
更新格式化程序的注册方式
public static class WebApiConfig {
public static void Register(HttpConfiguration config) {
// Other stuff...
var jsonFormatter = new MyJsonFormatter();
config.Formatters.Clear();
config.Formatters.Insert(0, jsonFormatter);
//...
}
}
确保在启动或启动应用程序的任何地方都遵循建议的语法。
// configure Web Api
GlobalConfiguration.Configure(WebApiConfig.Register);
还有下面文章中提到的内容协商的过程
Supporting only JSON in ASP.NET Web API – the right way
根据您的示例进行调整,它看起来像
public class JsonContentNegotiator : IContentNegotiator {
MediaTypeHeaderValue mediaType = MediaTypeHeaderValue.Parse("application/json;charset=utf-8");
private readonly MyJsonFormatter _jsonFormatter;
public JsonContentNegotiator(MyJsonFormatter formatter) {
_jsonFormatter = formatter;
}
public ContentNegotiationResult Negotiate(Type type, HttpRequestMessage request, IEnumerable<MediaTypeFormatter> formatters) {
var result = new ContentNegotiationResult(_jsonFormatter, mediaType);
return result;
}
}
并针对您的 HttpConfiguration
var jsonFormatter = new MyJsonFormatter();
config.Formatters.Clear();
config.Formatters.Insert(0, jsonFormatter);
//update content negotiation
config.Services.Replace(typeof(IContentNegotiator), new JsonContentNegotiator(jsonFormatter));
最后要注意的一条信息是框架确实将其 JSON 格式与其自身的 JsonMediaTypeFormatter
/// <summary>
/// Gets the <see cref="MediaTypeFormatter"/> to use for Json.
/// </summary>
public JsonMediaTypeFormatter JsonFormatter
{
get { return Items.OfType<JsonMediaTypeFormatter>().FirstOrDefault(); }
}
因此,取决于有多少管道实际上取决于 JsonMediaTypeFormatter
实例的存在,它可能会影响 JSON 相关格式。
如果这确实是一个问题,那么我的建议是从 JsonMediaTypeFormatter
派生并根据需要覆盖其成员。
public class MyJsonFormatter : JsonMediaTypeFormatter {
//... removed for brevity
}
但这可能会带来自身的问题,具体取决于基数 class 耦合的对象。