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)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM