我正在使用 Json.NET 序列化程序使用 Microsoft WebAPI,并且正在尝试使用控制器参数绑定将 Castle DictionaryAdapter 实例化为 JSON 的反序列化对象。(这将允许我们检测某些属性是否在 JSON 中设置为 null,或者它们是否默认为 null,因为它们不在 JSON 中,而不必放弃内置的解析和绑定机制。)
但它不起作用,因为新对象在创建和传递给控制器之间消失了。
控制器使用接口参数声明:
public interface IMessageModel
{
string Message { get; set; }
}
.
.
.
public HttpResponseMessage Patch(IMessageModel model)
我希望反序列化器实例化一个实现 IMessageModel 的 Castle DictionaryAdapter。
为此,我创建了 CustomCreationConverter 的子类,该子类由 DictionaryAdapterFactory 构造并覆盖 Create() 方法以返回动态 Castle 对象:
public class MessageModelConverter
: CustomCreationConverter<IMessageModel>
{
private DictionaryAdapterFactory m_adapterFactory;
public MessageModelConverter(DictionaryAdapterFactory adapterFactory)
{
m_adapterFactory = adapterFactory;
}
public override IMessageModel Create(Type objectType)
{
IMessageModel model = m_adapterFactory
.GetAdapter<IMessageModel>(new Hashtable());
return model;
}
}
然后我向 HttpConfiguration 对象添加一个格式化程序,如下所示:
DictionaryAdapterFactory adapterFactory = new DictionaryAdapterFactory();
config.Formatters.JsonFormatter.SerializerSettings.Converters
.Add(new MessageModelConverter(adapterFactory));
逐步调试调试器,我可以确认使用了 MessageModelConverter,调用了 Create(),并为实现 IMessageModel 的模型创建并返回了 Castle 代理。但是,当调用控制器时,模型参数为空。不知何故,实例化的类在转换器中的创建和控制器中的使用之间消失了。
但是,如果我将 Create 更改为使用实现 IMessageModel 的具体类,则一切正常,并且模型显示在控制器上:
public class MessageModel : IMessageModel
{
public string Message { get; set; }
}
.
.
.
public override IMessageModel Create(Type objectType)
{
IMessageModel model = new MessageModel();
return model;
}
或者,我可以声明一个实现 IMessageModel 并将所有调用委托给另一个接口对象的包装器,如下所示:
public class MessageModelWrapper : IMessageModel
{
public IMessageModel ContainedModel;
public MessageModelWrapper(IMessageModel containedModel)
{
ContainedModel = containedModel;
}
public string Message
{
get { return ContainedModel.Message; }
set { ContainedModel.Message = value; }
}
}
然后我像这样实现 Create():
public override IMessageModel Create(Type objectType)
{
IMessageModel model = m_adapterFactory
.GetAdapter<IMessageModel>(new Hashtable());
model = new MessageModelWrapper(model);
return model;
}
这让我可以在 Castle DictionaryAdapter 中走私,而且效果也很好。模型包装器到达控制器,我可以提取字典适配器代理。
但是当我直接创建并返回 Castle DictionaryAdapter 时,控制器仍然只是得到一个空值。
知道为什么 WebAPI 讨厌 Castle DictionaryAdapter 吗?