为什么ASP.NET MVC默认模型绑定是慢?它的花费很长的时间做工作 [英] Why ASP.NET MVC default Model Binder is slow? It's taking a long time to do its work
问题描述
在当前项目的客户要求在两个方面回答问卷的可能性:使用向导
(一个问题在一个时间)和清单
在一个单一的形式(一次全部问题)。这两种方式都已经实现了。
In a current project the client asked for the possibility of answering a questionnaire in two ways: using a Wizard
(one question at a time) and Listing
(all questions at once) in a single form. Both ways are already implemented.
该问题是由每使用AJAX手册的章数据库加载(这是超级快)。目前最大的章有 230
题(每题有4个HTML输入字段 - 输入/文本,选择等)。如果用户选择这样的章节在清单
格式回答,在<形式>
将包含约 920
字段被发送到服务器。
The questions are loaded from the database per Manual's chapter using AJAX (this is super fast). The biggest chapter at the moment has 230
questions (each with 4 HTML input fields - input/text, select, etc). If the user selects such Chapter to answer in the Listing
format, the <form>
will contain at about 920
fields to be posted to the server.
我在做一个AJAX POST请求传递数据与jQuery的连载
方法:
I'm doing an AJAX POST request passing the data with jQuery's serialize
method:
data: $("#questions :input").serialize()
此序列化发生 207.143ms
来完成。我与萤火虫这个值调试在Firefox:
This serialization takes 207.143ms
to complete. I got this value debugging with Firebug in Firefox:
console.profile();
$("#questions :input").serialize();
console.profileEnd();
这又是超级快...
Again this is super fast...
问题是当以下操作方法补水接收到的数据:
The problem comes when hydrating the data received on the following action method:
public async Task<ActionResult> ListSaveAsync(IEnumerable<AnswerViewModel> questions)
正如你看到的,发布的数据绑定到数据的IEnumerable&LT; AnswerViewModel&GT;问题
。 AnswerViewModel
只有4个字段存储每个答案。
As you see, the posted data is data bound to an IEnumerable<AnswerViewModel> questions
. AnswerViewModel
has only 4 fields to store each answer.
问题是,它需要相当长的时间(precisely 10秒)点击保存按钮打到这个动作方法中设置断点后,也就是这10秒被模型中的粘结剂$花p $ psumably。
The thing is that it takes a considerable amount of time (precisely 10 seconds) after clicking the Save button to hit a breakpoint on this action method, that is, those 10 seconds are being spent in the model binder presumably.
提一个重要的事情是,我用史蒂夫·桑德森的<一个href=\"http://blog.stevensanderson.com/2008/12/22/editing-a-variable-length-list-of-items-in-aspnet-mvc/\">@Html.BeginCollectionItem帮手帮助物化从HTTP POST视图模型集合属性时。看到这些数据的视图模型(钥匙)如何获得:
An important thing to mention is that I'm using Steve Sanderson's @Html.BeginCollectionItem helper to help when materializing the ViewModel collection properties from the HTTP POST. See how the data gets in the ViewModel (Keys):
你知道我可以尝试做优化呢?
Do you know what I can try to do to optimize this?
我想过4解决方法:
-
救回来只是修改问题。要做到这一点我需要每个答案值存储在一个数据属性装入上市时,它与实际值进行比较提交
&LT时;形式&GT;
,因为这帅哥建议 href=\"http://stackoverflow.com/a/8043489/114029\">。
Save back only the modified questions. To do this I'd need to store each answer value in a data-attribute when loading the listing and compare it with the actual value when submitting the
<form>
as this guy suggests here.
创建客户端上的 AnswerViewModel
JavaScript对象,并将其传递给操作方法。这会缓解模型绑定?
Create AnswerViewModel
JavaScript objects on the client side and pass them to the action method. Would this alleviate the Model Binder?
推出自己的模型绑定...但我真的不知道这是否会比自带的ASP.NET MVC默认的更快。从我读过的默认模型绑定做了很多反思的设定值/滋润作用的模型参数,这可能是瓶颈。
Roll my own model binder... but I really don't know if it would be faster than the default one that comes with ASP.NET MVC. From what I've read the default model binder does a lot of reflection to set the values/hydrate the action's model parameter and this could be the bottleneck.
使用的FormCollection
,并通过发布的数据手动过得去键和执行验证每一个枚举值如图所示<一个href=\"http://stack247.word$p$pss.com/2011/03/20/iterate-through-system-web-mvc-formcollection/\">here.
Use FormCollection
and enumerate through the posted data getting each value by key and performing validation manually as shown here.
你认为还有什么?
更新1
我去选项3,实现了自定义模型绑定: AnswerModelBinder:IModelBinder
,并在具体的操作方法用它:
I went with option 3 and implemented a custom Model Binder: AnswerModelBinder : IModelBinder
and used it in that specific action method:
public async Task<ActionResult> ListSaveAsync(
[ModelBinder(typeof(AnswerModelBinder))]List<AnswerViewModel> questions)
现在什么了 2的秒。
。
- 貌似默认的模型绑定验证检查[
的ModelState
]对性能有很大的影响。
- Looks like the default model binder validation checks [
ModelState
] has a big impact on performance.
更新2
我刚刚经历了一次又一次:具有列表&LT;的Guid&GT;
作为操作的参数,只有通过 59串
通过 $。的getJSON
呼叫正在采取〜3秒命中一个断点在动作方法的第一行。更改参数类型为列表&LT;串&gt;在一个眨眼
使得整个啄工作
I just experienced it once again: having a List<Guid>
as an action parameter and passing only 59 strings
through a $.getJson
call was taking ~3 seconds to hit a breakpoint in the 1st line of the action method. Changing the parameter type to List<string>
made the whole thingy work in the blink of an eye.
一个有趣的事实是,操作方法里面我这样做:
An interesting fact is that inside the action method I did this:
List<Guid> userIds = resources.Select(Guid.Parse).ToList();
和它转换的资源列表&LT;串&GT;
到列表&LT;的Guid方式&gt;
立即
有关肯定有一些车用ASP.NET模型粘合剂。我只是想知道它是什么...:)
For sure there's something buggy with ASP.NET model binder. I just would like to know what it is... :)
推荐答案
您可以使用ServiceStack JsonSerializer这是pretty快基准测试结果
这里是文档
http://mono.servicestack.net/docs/text-serializers/json-serializer
这里是基准
http://mono.servicestack.net/benchmarks/
You can use ServiceStack JsonSerializer which is pretty fast in benchmark results here is documentation http://mono.servicestack.net/docs/text-serializers/json-serializer and here is the benchmarks http://mono.servicestack.net/benchmarks/
这篇关于为什么ASP.NET MVC默认模型绑定是慢?它的花费很长的时间做工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!