WebAPI在返回JSON时序列化从抽象类型派生的类,而不是XML

时间:2017-02-04 01:00:48

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

我的模特:

    public abstract class BaseClass
    {
        public string id { get; set; }    
    }

    [KnownType(typeof(BaseClass))]
    public class ChildClass1 : BaseClass
    {
        public string shape { get; set; }
    }

    [KnownType(typeof(BaseClass))]
    public class ChildClass2: BaseClass
    {
        public string color { get; set; }
    }

    public class Widget
    {
        public List<BaseClass> Contents { get; set; }
        public Widget()
        {
            Contents = new List<BaseClass>();
        }    
    }

我的网络API端点:

        [HttpGet]
        public Widget Get()
        {
            Widget widget = new Widget();
            ChildClass1 cc1 = new ChildClass1();
            cc1.id = "1234";
            cc1.shape = "round";
            ChildClass2 cc2 = new ChildClass2();
            cc2.id = "4321";
            cc2.color = "red";
            widget.Contents.Add(cc1);
            widget.Contents.Add(cc2);
            return widget;
        }

在以XML格式请求输出时,它在序列化派生类时遇到问题。

  

&#39; ObjectContent`1&#39;类型无法序列化响应正文   内容类型&#39; application / xml;字符集= UTF-8&#39;

     

键入&#39; WebApplication1.Models.ChildClass1&#39;与数据合同名称   &#39; ChildClass1:http://schemas.datacontract.org/2004/07/WebApplication1.Models&#39;   不是预期的。如果是的话,请考虑使用DataContractResolver   使用DataContractSerializer或添加静态未知的任何类型   已知类型的列表 - 例如,通过使用KnownTypeAttribute   属性或将它们添加到传递给的已知类型列表中   串行器。

1 个答案:

答案 0 :(得分:2)

您应该向KnownType类添加Widget个属性,并指定可以作为BaseClass列表的Contents个实例传递的所有可能类型:

[KnownType(typeof(ChildClass1))]
[KnownType(typeof(ChildClass2))]
public class Widget
{        
    public List<BaseClass> Contents { get; set; }
    public Widget()
    {
        Contents = new List<BaseClass>();
    }
}

序列化回复:

<Widget xmlns:i="http://www.w3.org/2001/XMLSchema-instance"
        xmlns="http://schemas.datacontract.org/2004/07/YourNamespace">
    <Contents>
        <BaseClass i:type="ChildClass1">
            <id>1234</id>
            <shape>round</shape>
        </BaseClass>
        <BaseClass i:type="ChildClass2">
            <id>4321</id>
            <color>red</color>
        </BaseClass>
    </Contents>
</Widget>