我对 Asp.net Web Api 有以下问题。我尝试使用以下对象作为我的操作的参数
[DataContract]
public class MyObject
{
[DataMember]
public object MyIdProperty {get;set;}
}
MyIdProperty 属性可以包含 Guid 或 Int32
在 MVC 中,我做了一个 ModelBinder,它就像一个魅力,所以我为 WebApi 做了一个这样的
public class HttpObjectIdPropertyModelBinder : IModelBinder
{
public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext)
{
if (bindingContext.ModelType != ObjectType
|| (bindingContext.ModelName.TrimHasValue()
&& !bindingContext.ModelName.EndsWith("Id", StringComparison.OrdinalIgnoreCase)))
{
return false;
}
ValueProviderResult result = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
if (result == null || result.RawValue == null || result.RawValue.GetType() == ObjectType)
{
bindingContext.Model = null;
return true;
}
bindingContext.ModelState.SetModelValue(bindingContext.ModelName, result);
string stringValue = result.RawValue as string;
if (stringValue == null)
{
string[] stringValues = result.RawValue as string[];
if (stringValues != null && stringValues.Length == 1)
{
stringValue = stringValues[0];
}
if (stringValue == null)
{
return false;
}
}
Guid guid;
int integer;
if (Guid.TryParse(stringValue, out guid))
{
bindingContext.Model = guid;
}
else if (int.TryParse(stringValue, out integer))
{
bindingContext.Model = integer;
}
else
{
return false;
}
return true;
}
private static readonly Type ObjectType = typeof(object);
private static HttpParameterBinding EvaluateRule(HttpObjectIdPropertyModelBinder binder, HttpParameterDescriptor parameter)
{
if (parameter.ParameterType == ObjectType
&& parameter.ParameterName.EndsWith("Id", StringComparison.OrdinalIgnoreCase))
{
return parameter.BindWithModelBinding(binder);
}
return null;
}
public static void Register()
{
var binder = new HttpObjectIdPropertyModelBinder();
GlobalConfiguration.Configuration.Services.Insert(typeof(ModelBinderProvider), 0, new SimpleModelBinderProvider(typeof(object), binder));
GlobalConfiguration.Configuration.ParameterBindingRules.Insert(0, param => EvaluateRule(binder, param));
}
}
这是我第一次为 WebApi 做模型绑定器,所以我什至不确定我是否做得很好,以及它是否是解决这个问题的好方法。
无论如何,如果我有这样的动作,这个模型活页夹
public IEnumerable<MyObject> Get(object id)
{
// code here...
}
使用 Json 格式化程序或 Xml 格式化程序和模型绑定器正确反序列化参数 id
但是,如果我使用以下操作
public void Post(MyObject myObject)
{
// code here...
}
当我使用 Xml 格式化程序时,参数 myObject 被完美地反序列化,但是当我使用 Json 格式化程序时,属性 MyIdProperty 包含一个字符串而不是 Guid 或 Int32。在这两种情况下,我的模型活页夹根本没有使用。与 MVC 相比,它在动作参数处停止对模型的评估,MVC 为每个具有复杂类型的属性使用模型绑定器。
注意:我不想使用 true 类型或使用带有 true 类型的内部或受保护属性,因为我在很多不同的对象中都有这种属性,如果我必须复制代码将变得非常难以维护他们每次