ASP.NET Web API XmlFormatter不起作用,退回到JsonFormatter

时间:2014-04-07 15:42:53

标签: c# asp.net asp.net-web-api datacontractserializer

过去两天我一直在拔头发,想弄清楚为什么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]。

1 个答案:

答案 0 :(得分:1)

您的诊断方法是正确的,是的,Web API的内容协商过程将尝试根据一堆逻辑找到最佳格式化程序(例如:如果存在则接受标头,如果Accept-Header不存在则为Content-Type标头,请询问每个格式化程序如果它可以序列化类型等。)。

您可以通过执行以下操作来禁用此默认行为(即,在可以写入/序列化类型的格式化程序列表中查找第一个格式化程序)。这将导致生成406 Not Acceptable响应:

DefaultContentNegotiator negotiator = new DefaultContentNegotiator(excludeMatchOnTypeOnly: true);
config.Services.Replace(typeof(IContentNegotiator), negotiator);