为什么ASP.NET MVC默认模型绑定是慢?它的花费很长的时间做工作 [英] Why ASP.NET MVC default Model Binder is slow? It's taking a long time to do its work

查看:91
本文介绍了为什么ASP.NET MVC默认模型绑定是慢?它的花费很长的时间做工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在当前项目的客户要求在两个方面回答问卷的可能性:使用向导(一个问题在一个时间)和清单在一个单一的形式(一次全部问题)。这两种方式都已经实现了。

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帮手帮助物化从H​​TTP 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解决方法:


  1. 救回来只是修改问题。要做到这一点我需要每个答案值存储在一个数据属性装入上市时,它与实际值进行比较提交&LT时;形式&GT; ,因为这帅哥建议 href=\"http://stackoverflow.com/a/8043489/114029\">。

  1. 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆