在QQ群或者一些程式的交流平台,經常會有人問:我
怎麼傳一個數組在Action中接收、我
傳的數組為什麼Action的model中接收不到、或者我
在ajax的data中設定了一些數組,為什麼後台還是接收不了、還有一些
怎麼傳送一個複雜的對象或者
Action怎麼接收一個複雜的對象等等這些問題。或者有些人遇到複雜的對象或者數組直接就傳送個json字串,然後在Action中把json字串轉成model對象,當然這也是一種做法,但也許不是最優的做法。
一、需求
按照的資料格式,傳入到Action,用一個UserInfo Model接收,需求非常簡單。
分析後我們可以看到,其中愛好是個字串的數組,使用者包含一個公司對象,然後所包含的公司對象中又有個電話數組,使用者又包含數組對象,所以我們的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提交,我們所提交的資料大部分都是索引值對的格式,並不會直接傳入個json對象至後台,最多也只會傳入個字串的json,這個也許是受ajax data設定的誤導,很多人都會認為可以直接設定json對象提交至後台,也許格式簡單的Model可以接收到,但是複雜一點的,比如其中包含數組的等,即使json的格式和Model的格式一致,Model並不會接收到前台的提交的數組資料,這個也是我文章剛開始所提的一個問題。
為了驗證我說的ajax提交json格式的資料,我們做一下驗證。
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": "上海徐匯區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資料格式,如果我們背景model格式即使和data的資料格式一模一樣,也只有name一項可以正常接收到資料,其他的所有資料都將接收不到,至於為什麼。我們看一下jquery給我們轉成的索引值對的格式就應該知道了,我們從chrome或者Firefox的調試工具的network中可以看到提交的格式。
其中數組的格式為:xxxxxx[]的格式,對象中的對象格式為xxxx[yyyyy]格式,我沒有探究為什麼是這個格式,也許是其他的語言需要這樣的格式,php,jsp或者其他的語言吧,但asp.net mvc很明顯不需要這樣的格式。
後面是毀三觀的驗證,結果結果竟然全都能用Model接收到資料,接收到了,接收到,接收,接,了,我。。。。。。。。。突然感覺有一百個那個什麼飛過啊。。。。。。。。。。
我一度懷疑自己,難道之前做了幾年mvc的開發的模型繫結理解錯了,之前開發用jquery的ajax轉成的格式是不能接收到資料的啊,那是為什麼為什麼啊。經過探勘測試發現,我之前也沒有理解錯,原來是版本的問題。我測試是用的mvc5做的測試,mvc5可能對jquery ajax轉成的格式做了最佳化,但是mvc5之前的版本是不可以的,這個是重點。
那也就是說,如果你用的mvc5做的開發,反而簡單了很多,可以直接在ajax的data設定json格式的資料,複雜的,數組都可以,也許微軟開發人員也發現了這個問題,在mvc5解決了,我並沒有去研究源碼的區別,總之呢,mvc5是可以的。那mvc5以前的版本就會遇到我說的那個問題了。
三、模型繫結分析
部落格類比的表單已經可以包含網站開發過程中遇到的大部分的表單格式了,包含一些數組、對象等等。
從以前的開發的mvc項目中,發現了一些模型繫結的規律,區別在於數組和對象中的對象。
下面的圖片是手動轉成索引值對的值,mvc5之前的版本可以適用的格式,當然mvc5也是可以識別的,或者說這個格式是所有的mvc版本都可以適用的格式。
是兩種格式的對比圖
關於其中的規則,自己總結吧,應該很簡單了。
有人會問,手動拼的格式應該怎麼拼呢,這裡經常用的有兩種格式。
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); }});
使用者可以根據情況選擇不同的拼接方式。
四、總結
順便分享一個技巧,就是當我們拿到一段json的時候,別急著在類中建立model,一個一個類,一個一個的屬相敲,vs已經提供了一個很強大的工具,知道的可以忽略本段。
源碼地址Github: