1

我对 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 类型的内部或受保护属性,因为我在很多不同的对象中都有这种属性,如果我必须复制代码将变得非常难以维护他们每次

4

0 回答 0