在QQ群或者一些程序的交流平臺,經常會有人問:我怎么傳一個數(shù)組在Action中接收、我傳的數(shù)組為什么Action的model中接收不到、或者我在ajax的data中設置了一些數(shù)組,為什么后臺還是接收不了、還有一些怎么傳送一個復雜的對象或者Action怎么接收一個復雜的對象等等這些問題?;蛘哂行┤擞龅綇碗s的對象或者數(shù)組直接就傳送個json字符串,然后在Action中把json字符串轉成model對象,當然這也是一種做法,但也許不是最優(yōu)的做法。
一、需求
按照如圖的數(shù)據(jù)格式,傳入到Action,用一個UserInfo Model接收,需求非常簡單。
分析后我們可以看到,其中愛好是個字符串的數(shù)組,用戶包含一個公司對象,然后所包含的公司對象中又有個電話數(shù)組,用戶又包含數(shù)組對象,所以我們的Model應該是:
public class UserInfo { public string Name { get; set; } public int Age { get; set; } public string[] Bobbys { get; set; } public Company Company { get; set; } public Star[] Star { get; set; } }public class Company { public string Name { get; set; } public string Address { get; set; } public string[] Tel { get; set; } }public class Star { public string Name { get; set; } public int Age { get; set; } public string Movie { get; set; } }
二、表單提交掃盲與驗證
我們在提交表單時不管是post還是get提交,我們所提交的數(shù)據(jù)大部分都是鍵值對的格式,并不會直接傳入個json對象至后臺,最多也只會傳入個字符串的json,這個也許是受ajax data設置的誤導,很多人都會認為可以直接設置json對象提交至后臺,也許格式簡單的Model可以接收到,但是復雜一點的,比如其中包含數(shù)組的等,即使json的格式和Model的格式一致,Model并不會接收到前臺的提交的數(shù)組數(shù)據(jù),這個也是我文章剛開始所提的一個問題。
為了驗證我說的ajax提交json格式的數(shù)據(jù),我們做一下驗證。
Action:
[HttpPost]public ActionResult Index(UserInfo user) { return Json(user); }
Ajax:
$.ajax({ url: "/", type: "post", data: { "name": "Emrys", "age": "26", "bobbys": ["足球", "電影"], "company": { "name": "上海xxxxxx公司", "address": "上海徐匯區(qū)xxxx路", "tel": [ "021-88888881", "021-88888882", "021-88888883", "021-88888884" ] }, "star": [ { "name": "成龍", "age": "63", "movie": "十二生肖" }, { "name": "劉亦菲", "age": "18", "movie": "功夫之王" }, { "name": "胡歌", "age": "24", "movie": "瑯琊榜" } ] }, success: function (r) { console.log(r); } });
這個是我們經常提交的data數(shù)據(jù)格式,如果我們后臺的model格式即使和data的數(shù)據(jù)格式一模一樣,也只有name一項可以正常接收到數(shù)據(jù),其他的所有數(shù)據(jù)都將接收不到,至于為什么。我們看一下jquery給我們轉成的鍵值對的格式就應該知道了,我們從chrome或者火狐的調試工具的network中可以看到提交的格式。
其中數(shù)組的格式為:xxxxxx[]的格式,對象中的對象格式為xxxx[yyyyy]格式,我沒有探究為什么是這個格式,也許是其他的語言需要這樣的格式,php,jsp或者其他的語言吧,但asp.net mvc很明顯不需要這樣的格式。
后面是毀三觀的驗證,結果結果竟然全都能用Model接收到數(shù)據(jù),接收到了,接收到,接收,接,了,我。。。。。。。。。突然感覺有一百個那個什么飛過啊。。。。。。。。。。
我一度懷疑自己,難道之前做了幾年mvc的開發(fā)的模型綁定理解錯了,之前開發(fā)用jquery的ajax轉成的格式是不能接收到數(shù)據(jù)的啊,那是為什么為什么啊。經過探索測試發(fā)現(xiàn),我之前也沒有理解錯,原來是版本的問題。我測試是用的mvc5做的測試,mvc5可能對jquery ajax轉成的格式做了優(yōu)化,但是mvc5之前的版本是不可以的,這個是重點。
那也就是說,如果你用的mvc5做的開發(fā),反而簡單了很多,可以直接在ajax的data設置json格式的數(shù)據(jù),復雜的,數(shù)組都可以,也許微軟開發(fā)人員也發(fā)現(xiàn)了這個問題,在mvc5解決了,我并沒有去研究源碼的區(qū)別,總之呢,mvc5是可以的。那mvc5以前的版本就會遇到我說的那個問題了。
三、模型綁定分析
博客模擬的表單已經可以包含網站開發(fā)過程中遇到的大部分的表單格式了,包含一些數(shù)組、對象等等。
從以前的開發(fā)的mvc項目中,發(fā)現(xiàn)了一些模型綁定的規(guī)律,區(qū)別在于數(shù)組和對象中的對象。
下面的圖片是手動轉成鍵值對的值,mvc5之前的版本可以適用的格式,當然mvc5也是可以識別的,或者說這個格式是所有的mvc版本都可以適用的格式。
下圖是兩種格式的對比圖
關于其中的規(guī)則,自己總結吧,應該很簡單了。
有人會問,手動拼的格式應該怎么拼呢,這里經常用的有兩種格式。
1、直接拼接字符串
$.ajax({ url: "/", type: "post", data: "name=Emrys&age=26&bobbys[0]=足球&star[0].movie=瑯琊榜", success: function (r) { console.log(r); } });
2、javascript對象
var data1 = { name: "Emrys" }; data1.age = 26; data1["bobbys[0]"] = "足球"; data1["star[0].movie"] = "瑯琊榜"; $.ajax({ url: "/", type: "post", data: data1, success: function (r) { console.log("xxxxxxxxxxxxxx"); console.log(r); } });
用戶可以根據(jù)情況選擇不同的拼接方式。
四、總結
順便分享一個技巧,就是當我們拿到一段json的時候,別急著在類中新建model,一個一個類,一個一個的屬相敲,vs已經提供了一個很強大的工具,知道的可以忽略本段。
源碼地址Github:https://github.com/Emrys5/Asp.MVC-04-ModelBinding
以上就是關于模型綁定的一些應用,本文原創(chuàng),歡迎拍磚和推薦。
系列課程
作者:Emrys
出處:http://www.cnblogs.com/emrys5/
Asp.net mvc交流群:559422908
本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權利。
http://www.cnblogs.com/emrys5/p/asp-net-mvc-04-modelbinding.html