• 关于ASP.NET Web API的ModelBinding杂谈


    由于客户端调用Web API传递的数据属性命名一般偏向javascript规范,只是简单的大小写差异没有问题,但始终会有一些特殊情况。比如OAuth的请求:

    client_id : "value"
    client_secret : "value"

    在ASP.NET MVC开发时一般我们会开发一个ModelBinder,如果只是实现别名的绑定,继承DefaultModelBinder即可快速实现。下面的BindAliasModelBinder就是一个简单的实现参考:

    [AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
    public class BindAliasAttribute : Attribute
    {
        public BindAliasAttribute(string name)
        {
            this.Name = name;
        }
    
        public string Name { get; set; }
    }
    public abstract class AttributeModelBinder<TAttribute> : DefaultModelBinder
        where TAttribute : Attribute
    {
        protected override void BindProperty(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor)
        {
            base.BindProperty(controllerContext, bindingContext, propertyDescriptor);
    
            foreach (var attribute in propertyDescriptor.Attributes)
            {
                if (attribute is TAttribute)
                {
                    BindPropertyCore(controllerContext, bindingContext, propertyDescriptor, attribute as TAttribute);
    
                    break;
                }
            }
        }
    
        protected abstract void BindPropertyCore(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor, TAttribute attribute);
    }
    public class BindAliasModelBinder : AttributeModelBinder<BindAliasAttribute>
    {
        protected override void BindPropertyCore(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor, BindAliasAttribute attribute)
        {
            var value = controllerContext.HttpContext.Request.Params[attribute.Name];
            propertyDescriptor.SetValue(bindingContext.Model, value);
        }
    }

    然后我们在模型上这么使用它:

    [ModelBinder(typeof(BindAliasModelBinder))]
    public class OAuthModel
    {
        [BindAlias("client_id")]
        public string ClientId { get; set; }
    
        [BindAlias("redirect_uri")]
        public string RedirectUri { get; set; }
    }

    再来看Web API的模型绑定:System.Web.Http.ModelBinding.IModelBinder。只定义了一个方法"BindModel",需要实现和上面BindAliasModelBinder一样的功能有点太复杂了。这里有一个比较偷懒的推荐方式,就是将参数定义为一个JObject对象,调用它提供的ToObject<T>方法转换为实际的模型,这个时候就可以通过JsonPropertyAttribute解决映射的问题。例如:

    public AccessTokenResponse AccessToken(JObject content)
    {
        var request = content.ToObject<AccessTokenRequest>();
    
    }
  • 相关阅读:
    python正文(两)
    mysql计算指定的时间TPS
    wamp无法登录phpmyadmin问题
    BZOJ 1150 CTSC2007 数据备份Backup 堆+馋
    学习计划
    improper Advertising identifier [IDFA] Usage. Your app contains the Advertising Identifier [IDFA] AP
    让你的字ScrollView、ListView充分伸展
    HDU1237 简单的计算器 【堆】+【逆波兰式】
    Android硬件加速
    搭建MyBatis框架
  • 原文地址:https://www.cnblogs.com/junchu25/p/7494899.html
Copyright © 2020-2023  润新知