我想只绑定WebAPI控制器模型的指定属性,并跳过DefaultModelBinder
的所有其他属性。
例如我有json,应该传递给WebAPI控制器:
{
prop1: 1,
prop2: "b",
prop3: "c",
currentTime: "Fri Feb 27 2015",
references:
[
{ name: "Name 1", type: "Info" },
{ name: "Name 2", type: "Warn" }
]
}
在服务器端,有一个HttpPost
操作,其中包含以下签名:
[HttpPost]
public void SaveObject(ReferenceModel model)
{
...
}
ReferenceModel
的位置:
public class ReferenceModel
{
public int Prop1 {get; set;}
public string Prop2 {get; set;}
public string Prop3 {get; set;}
public DateTime CurrentTime {get; set;}
public List<BaseReferenceItem> References {get; set;}
}
我需要References
属性的自定义绑定,因为我想在运行时使用派生类型的对象初始化此属性。
例如,如果我的Prop1
值为1
,那么我需要使用DerivedReferenceType1
类型的对象初始化此集合:
Model.References = new List<BaseReferenceItem>()
{
new DerivedReferenceType1(){...},
new DerivedReferenceType1(){...}
}
如果我的Prop1
值为2
- 类型为DerivedReferenceType2
,依此类推。
我在ModelBinder
找到了可能的解决方案,但我不想绑定模型中的所有属性。
我知道可以通过调用
在MVC模型绑定器中轻松实现它base.BindModel(controllerContext, bindingContext);
但是如何在WebAPI中做到这一点?
谢谢!
答案 0 :(得分:1)
一种可能性是编写自定义JsonConverter
来处理这种情况:
public class MyConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(ReferenceModel);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
var jsonObject = JObject.Load(reader);
var result = new ReferenceModel();
serializer.Populate(jsonObject.CreateReader(), result);
result.References = new List<BaseReferenceItem>();
foreach (var obj in jsonObject.GetValue("references", StringComparison.InvariantCultureIgnoreCase))
{
if (result.Prop1 == 1)
{
result.References.Add(obj.ToObject<DerivedReferenceType1>(serializer));
}
else if (result.Prop1 == 2)
{
result.References.Add(obj.ToObject<DerivedReferenceType2>(serializer));
}
else
{
throw new NotSupportedException(result.Prop1 + " is not supported value for Prop1");
}
}
return result;
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
然后您可以使用此自定义转换器装饰主视图模型:
[JsonConverter(typeof(MyConverter))]
public class ReferenceModel
{
public int Prop1 { get; set; }
public string Prop2 { get; set; }
public string Prop3 { get; set; }
public DateTime CurrentTime { get; set; }
public List<BaseReferenceItem> References { get; set; }
}
或者如果您希望在不修改视图模型的情况下执行此操作,则可以始终在引导过程中注册自定义转换器:
public static void Register(HttpConfiguration config)
{
// Web API routes
...
var jsonFormatter = config.Formatters.JsonFormatter;
jsonFormatter.SerializerSettings.Converters.Add(new MyConverter());
}