zoukankan      html  css  js  c++  java
  • ASP.NET WebAPI 04 Model绑定

    在前面的几篇文章中我们都是采用在URI中元数据类型进行传参,实际上ASP.NET Web API也提供了对URI进行复杂参数的绑定方式--Model绑定。这里的Model可以简单的理解为目标Anction方法的某个参数。

    eg:

    public Figure GetFigureFromQueryString([ModelBinder]Figure figure)

    {

    return figure;

    }

    请求url: http://localhost:4044/api/Figure/GetFigureFromQueryString?FirstName=Bran&LastName=Stack

    结果:

    {

    "FirstName": "Bran",

    "LastName": "Stack"

    }

    (本篇为了更好的体现绑定结果,所有Anction的返回结果都是请求参数或整合的后的请求参数)

    ModelBinder

    在之前的文章中多次提到URI的数据主要来源于两种方式:Route,QueryString。但是URI只提供简单的基础数据类型,在上面的例中,我们会发现参数变成了类。ModelBinderAttribute提供了基础数据类型向复杂类型数据转换的功能。

    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Parameter, Inherited = true, AllowMultiple = false)]

    public class ModelBinderAttribute : ParameterBindingAttribute

    {

    }

    从定义中我们可以看出ModelBinder的AttributeUsage可以看出来ModelBinder可以用于类型与参数。下面我就列举一些Model绑定的形式。

    1. 简单类

    这里所说的简单类是指数据是指类的公开属性是基础数据类型。比如我们之前一直使用的Figure类。

    public class Figure

    {

    public string FirstName { get; set; }

    public string LastName { get; set; }

    }

    还是以本文开始的GetFigureFromQueryString([ModelBinder]Figure figure) 为例。因为该Action中只采用了一个参数。所以在传参的过程中只需要将FirstName,LastName作为QueryString传递,ModelBinder将转换出Figure对象。

    http://localhost:4044/api/Figure/GetFigureFromQueryString?FirstName=Bran&LastName=Stack

    同时我们也可以采用route形式进行传参:

    [Route("GetFigureFromRoute/{FirstName}/{LastName}")]

    public Figure GetFigureFromRoute(Figure figure)

    url:

    http://localhost:4044/api/Figure/GetFigureFromRoute/Bran/Stack

    当然以此类推也也可以进行混合的传参:

    还是基于 GetFigureFromRoute Action

    我们用以下url进行访问:

    http://localhost:4044/api/Figure/GetFigureFromRoute/Bran/Stack?FirstName=Robb

    那我们得到的结果将是:

    {

    "FirstName": "Robb",

    "LastName": "Stack"

    }

    由此可以看出

    QueryString参数的优先级是高于Route参数的

    2.多参数(简单类)

    第一种情况我们是考虑了一个参数,现在我们把参数变成两个,如下:

    List<Figure> 方法名 (Figure a, Figure b)

    因为这个时候出现了两个类型相同的参数,仅靠属性名已经不能对参数进行区别。这个时候WebAPI为我们提供了前缀形式对参数进行区分。下面就以Route的方式做一demo:、

    [Route("GetTwoFigureFromRoute/{a.FirstName}/{a.LastName}/{b.FirstName}/{b.LastName}")]

    public List<Figure> GetTwoFigureFromRoute(Figure a, Figure b)

    我们对路由进行一个简单分析:即{参数名}.{属性名} 作为路由的key

    {a.FirstName}:参数a的FirstName属性

    {a.LastName}:参数a的LastName属性

    {b.FirstName}:参数b的FirstName属性

    {b.LastName}:参数b的LastName属性

    用以下url访问

    http://localhost:4044/api/Figure/GetTwoFigureFromRoute/Bran/Stack/Robb/Stack

    得到的结果就是:

    [

    {

    "FirstName": "Bran",

    "LastName": "Stack"

    },

    {

    "FirstName": "Robb",

    "LastName": "Stack"

    }

    ]

    对于QueryString形式传参也非常简单,直接将{参数名}.{属性名} 作为QueryString的key.比如:

    public List<Figure> GetTwoFigureFromQueryString(Figure a, Figure b)

    url:

    http://localhost:4044/api/Figure/GetTwoFigureFromQueryString?a.FirstName=Bran&a.LastName=Stack&b.FirstName=Robb&b.LastName=Stack

    将得到如Route形式一样的结果

    3.复杂类

    现在我们对Figure添加一个Direwolf类的属性Direwolf,让其变为一个复杂类

    public class Figure

    {

    public Direwolf Direwolf { get; set; }

    }

    public class Direwolf

    {

    public string Name { get; set; }

    public string Color { get; set; }

    }

    在传参数的过程中显然我们不能对直接对Direwolf属性赋值,所以我们要对Direwolf属性进行拆分,这个时候我也要用到前缀的方式进行传参。如下:

    public Figure GetComplexFigureFromQueryString(Figure figure)

    url:

    http://localhost:4044/api/Figure/GetComplexFigureFromQueryString?FirstName=Jon&LastName=Snow&Direwolf.Color=White&Direwolf.Name=Summer

    结果:

    {

    "FirstName": "Bran",

    "LastName": "Stack",

    "Direwolf": {

    "Name": "Summer",

    "Color": "White"

    }

    }

    对于Route形式也是一样:

    [Route("GetComplexFigureFromRoute/{FirstName}/{LastName}/{Direwolf.Name}/{Direwolf.Color}")]

    public Figure GetComplexFigureFromRoute(Figure figure)

    url:

    http://localhost:4044/api/Figure/GetComplexFigureFromRoute/Bran/Stack/Grey/Summer

    对于多参数的形式也照样可以处理:

    public List<Figure> GetTwoComplexFigureFromQueryString(Figure a, Figure b)

    url:

    http://localhost:4044/api/Figure/GetTwoComplexFigureFromQueryString?a.FirstName=Bran&a.LastName=Stack&a.Direwolf.Color=Grey&a.Direwolf.Name=Summer&b.FirstName=Jon&b.LastName=Snow&b.Direwolf.Color=White&b.Direwolf.Name=Ghost

    4.集合类型

    集合类型因为存在长度的确定性,所以还是需要通过前缀的方式去指定序列号,如下:

    public List<int> GetList([ModelBinder] List<int> list)

    {

    return list;

    }

    url:

    http://localhost:4044/api/Figure/GetList?[0]=0&[1]=1&[2]=2&[3]=3

    结果:

    [

    0,

    1,

    2,

    3

    ]

    注意

    序列号必须是从0开始连续的整数,不然就只能得到序列号断裂之前的数据,如:

    url:

    http://localhost:4044/api/Figure/GetList?[0]=0&[2]=1&[2]=2&[3]=3

    结果:

    [

    0

    ]

    另外,如果要采用Route形式的传参方式,就必须考虑数据的长度问题。

    5字典类型

    WebAPI在数据字典类型的先将数据转化成KeyValuePair的集合类型,再转化成字典类型。所以再传参的时候我们可以采用与集合类型一致的方式。如:

    public Dictionary<string, int> GetDictionary([ModelBinder]Dictionary<string, int> dic)

    url:

    http://localhost:4044/api/Figure/GetDictionary?[0].Key=a&[0].Value=1&[1].Key=b&[1].Value=2

    结果

    {

    "a": 1,

    "b": 2

    }

    源码

    Github: https://github.com/BarlowDu/WebAPI (API_4)

  • 相关阅读:
    Window7下手动编译最新版的PCL库
    C和C++中的异常处理
    队列之卡片游戏
    C/C++笔记
    最真的梦——文/林清玄
    库函数与系统调用的区别
    hdu2653之BFS
    使用ffmpeg+crtmpserver搭建文件的伪直播
    ZOJ3705:Applications
    c_c++基础问题(平时读书时笔记)
  • 原文地址:https://www.cnblogs.com/gangtianci/p/4823927.html
Copyright © 2011-2022 走看看