我正在尝试将 Controller 操作绑定(bind)到接口(interface),但仍保持默认绑定(bind)行为。
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 中是一种黑客行为。我希望能够在服务中处理它。如果我将 CoolClass 指定为 Action 参数,它就可以正常工作。
我在这里找到了问题的部分解决方案 Dependency injection for ASP.NET Web API action method parameters但有一个后续问题。该解决方案不解析接口(interface)属性。请参阅下面的示例:
IConcreteClass 将被解析,但 ISubtype 不会。
public class SubConcreteClass : ISubtype
{
// properties
}
public class ConcreteClass : IConcreteClass
{
public ISubtype Subtype {get;set;}
}
一旦媒体格式化程序发现可以解析 IConcreteClass 中的类型,它就会读取整个流。所以我猜没有机会解析接口(interface)成员。
最佳答案
正如我上面提到的,action方法的接口(interface)参数可以使用DI来解析。但是该对象的接口(interface)成员需要以不同的方式处理。
我创建了 2 种类型的 JSON 转换器,一种是单一实体类型,另一种是集合类型,用于修饰接口(interface)属性。
这里有一个类需要解析为action接口(interface)参数。
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; }
}
这是 Controller 的 Action 方法
public HttpResponseMessage PostEnvelope(ICreateEnvelopeCommand model)
{
// do stuff
}
这是 2 个 JSON 转换器
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>));
}
}
关于c# - 使用默认行为将模型绑定(bind)到接口(interface),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18324070/