Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/36.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# webapi:The';CreateJsonSerializer';方法在尝试创建JSON序列化程序时引发异常_C#_Asp.net_Asp.net Web Api_Asp.net Web Api2 - Fatal编程技术网

C# webapi:The';CreateJsonSerializer';方法在尝试创建JSON序列化程序时引发异常

C# webapi:The';CreateJsonSerializer';方法在尝试创建JSON序列化程序时引发异常,c#,asp.net,asp.net-web-api,asp.net-web-api2,C#,Asp.net,Asp.net Web Api,Asp.net Web Api2,偶尔,我们会在活动环境中的ASP.NET Web API服务模块中观察到此错误,在应用程序池回收后,问题得到解决。此错误发生在发送响应时,一旦错误开始发生,所有后续请求都会因相同的错误而失败。但是,我们无法在较低的环境中重现此错误。即使使用简单的GET方法,也会出现错误 “stacktrace”:“在Sy stem.Net.Http.Formatting.BaseJsonMediaTypeFormatter.CreateJsonSerializerInternal()\r\n 在 System.

偶尔,我们会在活动环境中的ASP.NET Web API服务模块中观察到此错误,在应用程序池回收后,问题得到解决。此错误发生在发送响应时,一旦错误开始发生,所有后续请求都会因相同的错误而失败。但是,我们无法在较低的环境中重现此错误。即使使用简单的GET方法,也会出现错误

“stacktrace”:“在Sy stem.Net.Http.Formatting.BaseJsonMediaTypeFormatter.CreateJsonSerializerInternal()\r\n 在 System.Net.Http.Formatting.BaseJsonMediaTypeFormatter.WriteToStream(类型 类型、对象值、流写入流、编码 有效编码)\r\n位于 System.Net.Http.Formatting.JsonMediaTypeFormatter.WriteToStream(类型 类型、对象值、流写入流、编码 有效编码)\r\n位于 System.Net.Http.Formatting.BaseJsonMediaTypeFormatter.WriteToStreamAsync(类型 类型、对象值、流writeStream、HttpContent、, TransportContext TransportContext,CancellationToken cancellationToken)\r\n---来自上一个位置的堆栈结束跟踪 引发异常的位置---\r\n System.Runtime.CompilerServices.TaskWaiter.ThrowForNonSuccess(任务 任务)\r\n位于 System.Runtime.CompilerServices.TaskWaiter.HandleNonSuccessAndDebuggerNotification(任务 任务)\r\n位于 System.Web.Http.WebHost.HttpControllerHandler.d_u1b.MoveNext()“, “异常类”:“系统无效操作异常”,
“异常消息”:“CreateJsonSerializer”方法引发 尝试创建JSON序列化程序时发生异常

"

如果有人遇到此错误,请分享您的想法。

问题 我们最近遇到了一个与上述症状相同的问题

  • 在.Net Framework 4.6.1上使用IIS和ASP.Net Web API的网站
  • Web API请求在一段时间内运行良好,直到JSON序列化开始失败,导致参数绑定错误,如所述
  • 回收应用程序池或重新启动网站修复了该问题
我们案例中的问题是由于在Web API控制器代码中添加自定义Json.Net转换器的方式造成的

从控制器构造函数插入自定义转换器的方法如下:

public FruitController() {
    GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.Converters.Add(new AppleConverter());
    GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.Converters.Add(new PearConverter());
}
这意味着对于每个新的HTTP请求上下文,转换器被重新添加到静态转换器列表中。这就产生了两个问题,

  • 一种内存泄漏,当HTTP请求发出时,转换器列表会随着时间的推移而增加
  • 多个HTTP请求上下文线程可能同时尝试写入静态列表的并发问题
  • 第二个问题是在我们的案例中是什么导致了问题的发生

    多个线程试图添加到同一个静态.NET列表(即非线程安全)实现中,这导致列表中出现空条目。列表中的null converter条目导致Json.Net抛出异常,导致与发布的堆栈跟踪中显示的异常类似的异常。由于转换器列表中剩余的空条目,在此之后所有其他HTTP请求的JSON序列化都失败

    除了发布的堆栈跟踪,我们还观察到另一个堆栈跟踪,如

    在C:\Development\Releases\Json\Working\Newtonsoft.Json\Working-Signed\Src\Newtonsoft.Json\Json-serializer.GetMatchingConverter(IList`1 converters,类型objectType)中的Newtonsoft.Json.GetMatchingConverter(IList`1 converters,类型objectType):第1121行 在C:\Development\Releases\Json\Working\Newtonsoft.Json\Working Signed\Src\Newtonsoft.Json\Serialization\jsonserializer memberConverter,JsonContainerContract,JsonProperty containerProperty中的Newtonsoft.Json\Working-Signed\jsc\Newtonsoft.Json\Serialization\jsonserialization\jsonserializerizernalreader.cs:第396行 在C:\Development\Releases\Json\Working\Newtonsoft.Json\Working Signed\Src\Newtonsoft.Json\Serialization\jsonserialize\JsonSerializerInternalReader.cs中的Newtonsoft.Json.Serialization.Json反序列化(JsonReader阅读器,类型objectType,布尔checkAdditionalContent):第147行

    修复 为了解决这个问题,我们删除了在Web API控制器构造函数中添加JSON转换器的代码,并在应用程序启动线程中添加了转换器

    例如,在Global.asax中

    public class WebApiApplication : HttpApplication
    {
        protected void Application_Start()
        {
            /// ...
    
            var converters = GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.Converters;
    
            converters.Add(new FruitConverter());
            converters.Add(new PearConverter());
        }
    }