一段时间后,XML 模型绑定在 WebApi2 ASP.net 失败

XML model binding fails in ASP.net WebApi2 after a time

提问人:psaxton 提问时间:10/7/2016 最后编辑:psaxton 更新时间:10/18/2016 访问量:202

问:

我有几个托管在 TopShelf 容器中的 webapi 微服务,这些容器接受并使用 JSON 和 XML 格式化程序进行回复。运行一段时间后,XML 格式化程序将停止将 XML 请求数据绑定到模型。传递JSON或Form-Data仍然有效。指定导致 XML 响应的标头。重新启动服务后重播失败的 XML 请求将返回预期的响应Accept: application/xml

问题的根本原因是,当服务运行时,XmlFormatter 的属性会在某个时候被清除,并且模型绑定失败。SupportedMediaTypes

如何找到清除 SupportedMediaTypes 的内容?


调查问题时的注意事项如下。

我无法在可以将调试器连接到的任何环境中复制该问题。

当我在本地调试时,其中一个服务开始失败。据我所知,它选择 DataContractSerializer 而不是 XmlSerializer 进行反序列化。

Startup 类按以下顺序添加格式化程序:

config.Formatters.Clear();
config.Formatters.Add(new RecordSetMediaTypeFormatter<RecordAssociation>());
config.Formatters.Add(new XmlMediaTypeFormatter { UseXmlSerializer = true });
config.Formatters.Add(new XmlMediaTypeFormatter { UseXmlSerializer = false });
config.Formatters.Add(new JsonMediaTypeFormatter());

检查 HttpConfiguration 中的格式化程序顺序显示 XmlSerializer 格式化程序具有优先级:

> actionContext.RequestContext.Configuration.Formatters
Count = 4
    [0]: {API.Formatters.RecordSetMediaTypeFormatter<API.Contract.DataObjects.RecordAssociation>}
    [1]: {System.Net.Http.Formatting.XmlMediaTypeFormatter}
    [2]: {System.Net.Http.Formatting.XmlMediaTypeFormatter}
    [3]: {System.Net.Http.Formatting.JsonMediaTypeFormatter}
> (actionContext.RequestContext.Configuration.Formatters[1] as System.Net.Http.Formatting.XmlMediaTypeFormatter).UseXmlSerializer
true
> (actionContext.RequestContext.Configuration.Formatters[2] as System.Net.Http.Formatting.XmlMediaTypeFormatter).UseXmlSerializer
false

格式化程序指示它可以读取类型,但格式化程序是由集合选择的,即使使用:UseXmlSerializer == trueUseXmlSerializer == falseSystem.Object

> actionContext.RequestContext.Configuration.Formatters[1].CanReadType(typeof(System.Object))
true
> (actionContext.RequestContext.Configuration.Formatters.FindReader(typeof(System.Object), System.Net.Http.Headers.MediaTypeHeaderValue.Parse("application/xml")) as System.Net.Http.Formatting.XmlMediaTypeFormatter).UseXmlSerializer
false

为什么 MediaTypeFormatterCollection.FindReader 方法返回优先级较低的格式化程序?

在GitHub上检查源代码(感谢Microsoft!),我想看看这两个实例:MediaTypeFormatterCollectionSupportedMediaTypes

> actionContext.RequestContext.Configuration.Formatters[1].SupportedMediaTypes
Count = 0
> actionContext.RequestContext.Configuration.Formatters[2].SupportedMediaTypes
Count = 2
    [0]: {application/xml}
    [1]: {text/xml}

重新启动项目时,Formatters[1] 的集合与 Formatters[2] 的集合相同。

对项目中属性的唯一引用是在其构造函数中设置自己的属性。MediaTypeFormatter.SupportedMediaTypesRecordSetMediaTypeFormatterSupportedMediaTypes

什么是在运行时清除 XmlFormatter 的属性?SupportedMediaTypes

asp.net xml asp.net-web-api asp.net-web-api2

评论

0赞 NitinSingh 5/23/2018
嗨,您能够在这里找到问题所在吗?想知道为什么添加了两个具有 true/false 值的相同类型的格式化程序
0赞 psaxton 5/23/2018
我相信我最终将问题追溯到第三方库在加载特定类时清除了该属性。我只是为该功能使用了不同的库。当我有机会时,我必须检查源代码管理,看看我是否能找到库是什么。

答: 暂无答案