WebAPI JSON使用Object的属性进行反序列化

时间:2013-03-29 19:05:19

标签: c# xml json serialization asp.net-web-api

我对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属性,因为我在很多不同的对象中都有这种属性,如果我的代码将很难维护每次都必须复制它们

0 个答案:

没有答案