关于ASP.NET Web API的ModelBinding杂谈

摘要:
由于客户端调用WebAPI传递的数据属性命名一般偏向javascript规范,只是简单的大小写差异没有问题,但始终会有一些特殊情况。比如OAuth的请求:client_id:"value"client_secret:"value"在ASP.NETMVC开发时一般我们会开发一个ModelBinder,如果只是实现别名的绑定,继承DefaultModelBinder即可快速实现。下面的BindAliasModelBinder就是一个简单的实现参考:[AttributeUsage]publicclassBindAliasAttribute:Attribute{publicBindAliasAttribute{this.Name=name;}publicstringName{get;set;}}publicabstractclassAttributeModelBinder:DefaultModelBinderwhereTAttribute:Attribute{protectedoverridevoidBindProperty{base.BindProperty;foreach{if{BindPropertyCore;break;}}}protectedabstractvoidBindPropertyCore;}publicclassBindAliasModelBinder:AttributeModelBinder{protectedoverridevoidBindPropertyCore{varvalue=controllerContext.HttpContext.Request.Params[attribute.Name];propertyDescriptor.SetValue;}}然后我们在模型上这么使用它:[ModelBinder]publicclassOAuthModel{[BindAlias]publicstringClientId{get;set;}[BindAlias]publicstringRedirectUri{get;set;}}再来看WebAPI的模型绑定:System.Web.Http.ModelBinding.IModelBinder。只定义了一个方法"BindModel",需要实现和上面BindAliasModelBinder一样的功能有点太复杂了。

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

client_id : "value"
client_secret : "value"

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

[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
public classBindAliasAttribute : Attribute
{
    public BindAliasAttribute(stringname)
    {
        this.Name =name;
    }
    public string Name { get; set; }
}
public abstract class AttributeModelBinder<TAttribute>: DefaultModelBinder
    whereTAttribute : Attribute
{
    protected override voidBindProperty(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor)
    {
        base.BindProperty(controllerContext, bindingContext, propertyDescriptor);
        foreach (var attribute inpropertyDescriptor.Attributes)
        {
            if (attribute isTAttribute)
            {
                BindPropertyCore(controllerContext, bindingContext, propertyDescriptor, attribute asTAttribute);
                break;
            }
        }
    }
    protected abstract voidBindPropertyCore(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor, TAttribute attribute);
}
public class BindAliasModelBinder : AttributeModelBinder<BindAliasAttribute>
{
    protected override voidBindPropertyCore(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 classOAuthModel
{
    [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解决映射的问题。例如:

publicAccessTokenResponse AccessToken(JObject content)
{
    var request = content.ToObject<AccessTokenRequest>();
}

免责声明:文章转载自《关于ASP.NET Web API的ModelBinding杂谈》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇VGG16学习笔记KMO检验和Bartlett球形检验下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

随便看看

面试了一个 31岁的iOS开发者,思绪万千,30岁以上的程序员还有哪些出路?

前言之前HR给了我一份简历,刚看到简历的第一眼,31岁?31岁,iOS开发工程师,工作经历7年,5年左右都在外包公司,2年左右在创业公司。iOS开发工程师这块,还是很少遇到30岁以上的开发,正好,来了一个30岁的开发,说实话,对我来说,还是蛮期待的,希望对我有所启示。这样的过程持续了半个小时那么年过350岁的程序员还有出路吗?作为一个8年的iOS开发,而且几...

layui table 打印表格

例如,layui的表单打印方法是将表单的数据重新组合成新页面,但它只能打印当前页面的内容。仅仅说实话是不够的。我整个上午都找到了一些,并说他们自己换了,但他们并不满意。这没用。我只能打印当前页面的内容。我的想法是编写一个函数,传递显示的列和要打印的数据,然后直接打印。不要胡说八道。直接转到代码。...

数据库软考易混淆知识之信息化基础、项目管理

2、 关键路径关键路径是活动图中最长的路径示例:图中显示了软件项目的活动图,其中固定点表示项目里程碑,连接顶点的边表示包含的活动,边上的数字表示活动持续时间的天数,则完成项目的最短时间为()天,活动EH和IJ的放松时间分别为()日。...

JRebel激活服务搭建

前言因为平时的开发工具是使用IntelliJIDEA,所以热部署项目代码的时候,使用的Jrebel。因为Jrebel是收费的,所以以前用的时候都是在网上找破解方法,在网上找到的办法是输入一个在线激活服务,来进行激活。由于简单方便就一直这样用的,今天早上打开IDEA后发现,Jrebel激活失效了。JRebel很好用,也是离不开大家的支持,所以如果条件允许的话,...

python中将xml格式转json格式

通常需要处理xml格式的文件或字符串。由于json格式处理的方便,第2步:第1步:安装工具包xmltodict,在命令行中输入:pipinstallxmltodict2,并在代码中使用xmltodict.parse(xml_str)进行处理,例如reload_json(xml_path):#获取xml文件xml_file=open(xml_paath,...

异步处理在支付环节的应用

本文主要介绍同步和异步处理的基本概念,异步处理在支付过程中的应用,以及当支付系统通知商家支付结果时,为什么要使用“异步通知”?...