本篇文章給大家分享的是有關(guān)當(dāng)ASP.NET MVC邂逅jQuery.Ajax提交數(shù)組的示例分析,小編覺得挺實用的,因此分享給大家學(xué)習(xí),希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。
創(chuàng)新互聯(lián)公司專注于曲陽網(wǎng)站建設(shè)服務(wù)及定制,我們擁有豐富的企業(yè)做網(wǎng)站經(jīng)驗。 熱誠為您提供曲陽營銷型網(wǎng)站建設(shè),曲陽網(wǎng)站制作、曲陽網(wǎng)頁設(shè)計、曲陽網(wǎng)站官網(wǎng)定制、微信小程序服務(wù),打造曲陽網(wǎng)絡(luò)公司原創(chuàng)品牌,更為您提供曲陽網(wǎng)站排名全網(wǎng)營銷落地服務(wù)。
當(dāng)ASP.NET MVC 通過JQuery的Ajax 提交數(shù)組時,MVC的model binder機制就失效了。我們不得不在Controller里面編寫自定義代碼,將Request提交的數(shù)據(jù)轉(zhuǎn)換成需要的數(shù)據(jù)類型。這個過程往往枯燥乏味。下面以某項目的實際例子來演示如何解決這個問題,提供一個通用的解決方案。
需求描述
當(dāng)用戶更改了配置,需要Ajax提交到服務(wù)器。
前端代碼:
var items = []; $("input:checked").each(function () { items.push($(this).val()); }); $.ajax({ type: 'post', url: 'Configure/Status', data: { answers: items } });
后端代碼:
public enum AnswerStatus { Correct = 1, Incorrect = 2, Unanswered = 3 } [HttpPost] public ActionResult Status(IListanswers) { …. }
這里的answers始終為null. 神器fiddler出場,發(fā)現(xiàn)用JQuery.Ajax 提交Array的數(shù)據(jù),提交的時候始終會在名稱后面加上”[]”, 問題就出在這里。
根據(jù)發(fā)現(xiàn)的結(jié)果修改代碼:
[HttpPost] public ActionResult Status(IListanswers) { answers = Request.Form.GetValues(“answers[]”).Select(d => d.ToEnum (AnswerStatus.Unanswered).ToList(); }
雖然這樣能夠通過解決我的問題,但每次提交Array都要這樣手工解析request,視乎一夜回到石器時代了。其實我們馬上會想到MVC 的Mode Binder。
嘗試進行***次重構(gòu):
public class AnswerModelBinder : IModelBinder { public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) { return controllerContext.RequestContext.HttpContext.Request.Form.GetValues(“answers[]”).Select(d => d.ToEnum(AnswerStatus.Unanswered).ToList(); } }
硬編碼味道太重,換個類型又得重寫,工作量跟之前比還視乎增加了,只是Controller變得優(yōu)雅了。這種浪費青春又耗電的做法還是不符合要求。
進行第二次重構(gòu) : DefaultModelBinder 出場
***的DefaultModelBinder,能夠綁定任何類型,可惜就是client傳過來的name后面多加了”[]”,導(dǎo)致DefaultModelBinder無法準(zhǔn)確解析。那我們能不能欺騙DefaultModelBInder呢?
查看ModelBindingContext發(fā)現(xiàn)有一個ModelName屬性,感覺有點像要綁定的參數(shù)的名稱,調(diào)試跟蹤發(fā)現(xiàn)ModelName確實就是參數(shù)的名稱,那我們修改ModelName讓他跟client傳過來的name保持一致是否就能夠充分發(fā)揮DefaultModelBinder。于是動手創(chuàng)建一個JQAjaxModelBinder
并繼承自DefaultModelBinder:
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) { if(bindingContext.ModelType.IsEnumerable()) { var key = bindingContext.ModelName + "[]"; var valueResult = bindingContext.ValueProvider.GetValue(key); if(valueResult != null && !string.IsNullOrEmpty(valueResult.AttemptedValue)) { bindingContext.ModelName = key; } } return base.BindModel(controllerContext, bindingContext); }//如何使用自定義ModelBinder。該方法是Controller里面的Action public ActionResult Status([ModelBinder(typeof(ModelBinder.JQAjaxModelBinder))] IListanswers) { … }
這時,Controller里面的Status (Action)方法已經(jīng)能夠正確得到前端傳來的數(shù)據(jù)。并且還是強類型的。當(dāng)然很多程序員都是懶惰的,筆者也是這其中一份子。筆者連Parameter前面的參數(shù)([ModelBinder(typeof(ModelBinder.JQAjaxModelBinder))])都不想寫,那我們直接在ModelBinders里面注冊吧。其實注冊的時候也有點麻煩,必須設(shè)定Type,我那能提前知道有那些類型啊。干脆將JQAjaxModelBinder設(shè)置成默認(rèn)的ModerBinder,一勞永逸,再也沒有煩心事情了。
ModelBinder不同注冊方法
通過在Action方法的參數(shù)前面添加ModelBinder標(biāo)簽,上文則是采用的這種方法。
數(shù)據(jù)類型上面添加ModelBinder標(biāo)簽
[ModelBinder(typeof(ModelBinder.JQAjaxModelBinder))] Public class User { }
通過ModelBinders注冊
ModelBinders.Binders.Add(typeof(User), new ModelBinder.JQAjaxModelBinder());
設(shè)置默認(rèn)的ModerBinder
ModelBinders.Binders.DefaultBinder = new ModelBinder.JQAjaxModelBinder();
后記: 當(dāng)我們在開發(fā)的時候,經(jīng)常做重復(fù)的事情,當(dāng)一件事情重復(fù)多次后,我們就需要停下來認(rèn)真思考,能不能將這些事情抽象出來,做一個通用的解決方案呢?一勞永逸的解決這些問題。
以上就是當(dāng)ASP.NET MVC邂逅jQuery.Ajax提交數(shù)組的示例分析,小編相信有部分知識點可能是我們?nèi)粘9ぷ鲿姷交蛴玫降摹OM隳芡ㄟ^這篇文章學(xué)到更多知識。更多詳情敬請關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。