在當前的項目中,客戶要求以兩種方式回答調查問卷的可能性:一次使用Wizard
(一次提出一個問題)和Listing
(一次提出所有問題)形成。這兩種方式已經實施。爲什麼ASP.NET MVC的默認Model Binder速度很慢?需要很長時間才能完成工作
使用AJAX(這是超快速),每個手冊的章節都會從數據庫加載這些問題。目前最大的章節有230
問題(每個問題有4個HTML輸入字段 - 輸入/文本,選擇等)。如果用戶選擇此章節以Listing
格式回答,則<form>
將包含約920
字段以發佈到服務器。
我在做一個AJAX POST請求傳遞的數據與jQuery的serialize
方法:
data: $("#questions :input").serialize()
這種序列化發生207.143ms
完成。我在Firefox中使用Firebug這個值調試:
console.profile();
$("#questions :input").serialize();
console.profileEnd();
再次,這是超級快...
以下操作方法時,保溼接收到的數據的問題就來了:
public async Task<ActionResult> ListSaveAsync(IEnumerable<AnswerViewModel> questions)
如您所見,發佈的數據是綁定到IEnumerable<AnswerViewModel> questions
的數據。 AnswerViewModel
只有4個字段來存儲每個答案。
事情是,在點擊保存按鈕在這個動作方法上點擊一個斷點後,需要花費相當長的時間(正好是10秒),也就是說,這10秒將被用在模型聯編程序中。
需要注意的一個重要的事情是,我使用Steve Sanderson的@Html.BeginCollectionItem helper來幫助實現HTTP POST的ViewModel集合屬性。看到這些數據的視圖模型(鑰匙)如何到達:
你知道我可以嘗試做優化呢?
我想約4解決方法:
救回來只有修正的問題。要做到這一點,我需要在加載列表時將每個答案值存儲在數據屬性中,並在提交
<form>
時將其與實際值進行比較,因爲此人建議here。創建
AnswerViewModel
客戶端上的JavaScript對象並將它們傳遞給操作方法。這是否會緩解模型綁定器?滾動我自己的模型綁定器......但我真的不知道它是否會比ASP.NET MVC默認的快。從我讀過的默認模型綁定器中做了很多反射來設置值/水合動作的模型參數,這可能是瓶頸。
使用
FormCollection
並通過發佈的數據枚舉按鍵獲取每個值並手動執行驗證,如here所示。
您還建議了什麼?
更新1
我去選項3,實現了自定義的模型綁定:AnswerModelBinder : IModelBinder
並在具體操作方法使用它:
public async Task<ActionResult> ListSaveAsync(
[ModelBinder(typeof(AnswerModelBinder))]List<AnswerViewModel> questions)
現在什麼了10 seconds
完成只需要2 seconds
。
- 看起來像默認模型活頁夾驗證檢查[
ModelState
]對性能有很大影響。
更新2
我只經歷過一次:具有List<Guid>
作爲操作參數,只有通過59 strings
通過$.getJson
呼叫正在採取〜3秒命中一個斷點在一號線行動方法。將參數類型更改爲List<string>
使整件事情在眨眼之間起作用。
一個有趣的事實是,該操作方法裏面我這樣做:
List<Guid> userIds = resources.Select(Guid.Parse).ToList();
並把它轉換的資源List<string>
到List<Guid>
瞬間。
肯定有一些與ASP.NET模型綁定器錯誤。我只是想知道它是什麼... :)
很抱歉的緩慢回覆,Leniel。您發送給服務器的問題有多少?模型聯編程序使用大量代碼來試圖解析來自請求的輸入的通用性。我認爲在你的情況下,最好的解決辦法就是你走的路。 – OdeToCode 2013-02-21 21:44:47
@OdeToCode感謝Scott的採訪......不錯,您同意自定義模型活頁夾的方法。在這個特定的情況下,我向服務器發送了230個問題。如果我也選擇了#1選項,我認爲它會更快......;)可能是1s而不是2s,因爲JavaScript相當快。必須測試這個。 – 2013-02-21 22:53:45
@OdeToCode只補充了代碼並實現瞭解決方法#1上面提到的=>加載問題時,我將每個輸入/選擇當前值放入數據屬性中,當保存時,我將當前值與數據中先前的值進行比較屬性。然後,我使用jQuery的過濾功能來幫助解決這個問題。現在保存是即時的。 :-) jQuery代碼非常快! – 2013-02-22 04:58:54