我对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相比。
注意:我不想使用true类型或使用true类型的internal或protected属性,因为我在很多不同的对象中都有这种属性,如果我的代码将很难维护每次都必须复制它们