Web API模型绑定到接口 [英] web api model binding to an interface

查看:153
本文介绍了Web API模型绑定到接口的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图将控制器操作绑定到接口,但仍保持默认的绑定行为.

I'm trying to bind a controller action to an interface but still maintain the default binding behavior.

public class CoolClass : ISomeInterface
{
    public DoSomething {get;set;} // ISomeInterface
}

public class DosomethingController : ApiController
{
    public HttpResponseMessage Post(ISomeInterface model)
    {
        // do something with model which should be an instance of CoolClass
    }
} 

我的服务的使用者对CoolClass一无所知,因此,我认为让他们将"$ type"添加到他们正在传递的Json上将是一个hack.我希望能够在服务中处理它.如果我将CoolClass指定为action参数,则效果很好.

The consumer of my service knows nothing of CoolClass so having them add "$type" to the Json they are passing would be a hack in my opinion. I'd like to be able to handle it in the service. If I specify CoolClass as the action parameter it works fine.

所以我在这里

So I found a partial solution to my question here Dependency injection for ASP.NET Web API action method parameters but there is a follow up issue. That solution does not resolve interface properties. See my example below.

IConcreteClass将被解析,但ISubtype将无法解析.

IConcreteClass will be resolved, but ISubtype will not.

public class SubConcreteClass : ISubtype
{
    // properties
}

public class ConcreteClass : IConcreteClass
{
    public ISubtype Subtype {get;set;}
}

一旦媒体格式化程序看到可以解析IConcreteClass中的类型,则它将读取整个流.因此,我猜测没有机会解析接口成员.

Once the media formatter sees that is can resolve the type in IConcreteClass, it then reads the entire stream. So I'm guessing there is no chance to resolve interface members.

推荐答案

因此,如果这可以对其他人有所帮助,我将继续发布我想出的解决方案.

So in case this can help anyone else, I'll go ahead and post the solution I came up with.

如上所述,可以使用DI解析action方法的接口参数.但是该对象的接口成员需要以不同的方式处理.

As I mentioned above, the interface parameters of the action method can be resolved using DI. But the interface members of that object need to be handled differently.

我创建了两种类型的Json转换器(一个实体类型和一个集合类型)来装饰接口属性.

I created 2 types of Json converters, a single entity type and a collection type, to decorate the interface properties.

这是一个需要作为操作界面参数解析的类.

Here's a class that needs to be resolved as an action interface parameter.

public class CreateEnvelopeModel : ICreateEnvelopeCommand
{
    [JsonConverter(typeof(EntityModelConverter<CreateEmailModel, ICreateEmailCommand>))]
    public ICreateEmailCommand Email { get; set; }
    [JsonConverter(typeof(CollectionEntityConverter<CreateFormModel, ICreateFormCommand>))]
    public IList<ICreateFormCommand> Forms { get; set; }
}

这是控制器操作方法

public HttpResponseMessage PostEnvelope(ICreateEnvelopeCommand model)
{
    // do stuff
}

这是2个json转换器

Here's the 2 json converters

public class EntityModelConverter<T, Tt> : JsonConverter where T : Tt
{
    public override bool CanConvert(Type objectType)
    {
        return (objectType == typeof(Tt));
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        return serializer.Deserialize<T>(reader);
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        serializer.Serialize(writer, value, typeof(T));
    }
}

public class CollectionEntityConverter<T, Tt> : JsonConverter where T : Tt
{
    public override bool CanConvert(Type objectType)
    {
        return (objectType == typeof(IList<Tt>));
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        IList<Tt> items = serializer.Deserialize<List<T>>(reader).Cast<Tt>().ToList();
        return items;
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        serializer.Serialize(writer, value, typeof(IList<T>));
    }
}

这篇关于Web API模型绑定到接口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆