Web Api 2序列化抽象属性

时间:2015-07-01 13:30:17

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

我目前遇到的问题似乎无法找到答案。在我的web api 2项目中,我们使用post请求将资源添加到数据库。但是,在将JSON序列化为Model时,我遇到了一些实际上是抽象的模型属性的问题。让我来说明一下:

public class Person
{
    public string Name {get; set;}
    public virtual Address Address {get; set;}
}


public abstract class Address 
{
    public int Id {get; set;}
}

public class ConcreteAddressType1 : Address
{
    public string Street {get; set;}
}

public class ConcreteAddressType2 : Address
{
    public string POBox {get; set;}
}

ApiController Action看起来像这样:

[HttpPost]
public async Task<IHttpActionResult> Post([FromBody]Person person)
{
    // Validate and save to Database
    return person;      
}

目前开箱即用的这个属性Address始终为null,这是有道理的,因为它是抽象的,必须是序列化程序无法自行决定的两个具体实例之一。 因此,当将请求主体反序列化为Person实例时,我需要以某种方式&#34;检查传入的Json / XML的Address-field,并根据它确定它必须具体的类。两个Address-superclasses的字段不同,我可以决定它必须具体的类。

所以我尝试为Person和Address制作自定义模型绑定器,但它感觉不好,我只是想知道是否有办法使用常规的Web Api ModelBinder for Person工作完美地,只需为其中一个属性使用不同的自定义绑定器。

我在JSON.NET Abstract / Derived Class Deserialization with WebAPI 2找到了一些东西,但是,我需要一个没有client $ type参数的解决方案。 我还发现Web Api Model Binding and Polymorphic Inheritence看起来非常接近我的看法,但这是参数中的整个类,而不是它的一个属性。

最后,我发现我可以使用自定义模型绑定器执行类似的操作:

[HttpPost]
public async Task<IHttpActionResult> Post([FromBody]Person person, [ModelBinder(typeof(AdresModelBinder))]Address address)
{
    //The custom modelbinder has bound address to the correct concrete class
    person.Address = address

    // Validate and save to Database
    return person;      
}

但是出于可读性的原因,我想拥有一个输入参数和整个Person对象,并且单独的绑定和组合似乎容易出错,而不是在Controller-actions的范围内。

谢谢!

0 个答案:

没有答案