过去两天我一直在拔头发,想弄清楚为什么XmlFormatter(通过DataContractSerializer)不会序列化我在Web API方法中返回的数据。 WebAPI决定使用JSON,但我需要结果是XML(根据将使用此API的应用程序)。我已经设置我的浏览器发送Accept:application / xml for the resolver使用XmlFormatter(但结果总是json)。
控制器:
public class MyController : ApiController
{
public MyDataResultList GetData(string someArgument)
{
// magic here that gets the data
MyDataResultList items = MyDataResultList.GetData(someArgument);
return items;
}
}
MyDataResultList包含在dll中,并具有类似的布局:
[DataContract]
[CollectionDataContract(Name = "MyDataList")]
[KnownType(typeof(List<MyDataItem>))]
public class MyDataResultList : List<MyDataItem>
{
[DataMember]
public string SomethingHere
{
get;
set;
}
[DataMember]
public TimeSpan StartTime
{
get;
set;
}
[DataMember]
public TimeSpan StopTime
{
get;
set;
}
}
我尝试将 UseXmlSerializer 设置为true,但我需要在客户端使用DataContractSerializer来正确反序列化结果。
所以最后一个问题是,如果无法使用任何格式化程序首先进行序列化,是否可以配置Web API以引发异常?我相信(在我看来)它非常具有误导性和过于抽象,只是默默地回到JSON而不给我任何关于导致这种情况的线索。
更新:使用DCS手动序列化MyDataResultList抛出InvalidDataContractException:键入&#39; MyDataResultList&#39; CollectionDataContractAttribute属性是一个无效的集合类型,因为它具有DataContractAttribute属性。但基本问题仍然存在:如何让Web API向我抛出这个而不是默默地回归到JSON? (并使调试更加困难)
Update2: DataContract序列化程序似乎完全跳过SomethingHere / StartTime / EndTime属性,即使它们上有[DataMember]。
答案 0 :(得分:1)
您的诊断方法是正确的,是的,Web API的内容协商过程将尝试根据一堆逻辑找到最佳格式化程序(例如:如果存在则接受标头,如果Accept-Header不存在则为Content-Type标头,请询问每个格式化程序如果它可以序列化类型等。)。
您可以通过执行以下操作来禁用此默认行为(即,在可以写入/序列化类型的格式化程序列表中查找第一个格式化程序)。这将导致生成406 Not Acceptable
响应:
DefaultContentNegotiator negotiator = new DefaultContentNegotiator(excludeMatchOnTypeOnly: true);
config.Services.Replace(typeof(IContentNegotiator), negotiator);