在当前的项目中,客户要求以两种方式回答问卷的可能性:在单一形式中使用Wizard
(一次一个问题)和Listing
(一次所有问题)。这两种方法都已经实现了。
根据手册的章节,问题是使用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个字段来存储每个答案。
问题是,在单击Save按钮之后需要相当长的时间(准确地说是10秒)来命中此操作方法上的断点,也就是说,这10秒大概是在模型绑定器中花费的。
值得一提的是,在实现HTTP POST中的ViewModel集合属性时,我使用Steve Sanderson的@Html.BeginCollectionItem helper来提供帮助。查看数据是如何进入ViewModel (键)的:
你知道我可以尝试做些什么来优化它吗?
我想了4个变通办法:
AnswerViewModel
JavaScript对象,并将它们传递给操作方法。这会减轻模型活页夹的压力吗?FormCollection
并枚举发布的数据,通过键获取每个值并手动执行验证,如here.所示
你还有什么建议吗?
更新1
我选择了选项3,实现了一个自定义的模型绑定器:AnswerModelBinder : IModelBinder
,并在那个特定的操作方法中使用了它:
public async Task<ActionResult> ListSaveAsync(
[ModelBinder(typeof(AnswerModelBinder))]List<AnswerViewModel> questions)
现在,只需要2 seconds
就可以完成10 seconds
所需的功能。
有很大影响的默认模型绑定器验证检查ModelState
更新2
我刚刚又经历了一次:使用List<Guid>
作为操作参数,并且只通过$.getJson
调用传递59 strings
,大约需要3秒才能命中操作方法第一行中的断点。将参数类型更改为List<string>
可以使整个操作在一眨眼的时间内完成。
一个有趣的事实是,在action方法中,我这样做了:
List<Guid> userIds = resources.Select(Guid.Parse).ToList();
并且它即时地将资源List<string>
转换为List<Guid>
。
可以肯定的是,ASP.NET模型绑定器有一些缺陷。我只想知道那是什么..。:)
发布于 2014-03-21 17:11:17
您可以使用ServiceStack JsonSerializer,它在基准测试结果中速度非常快,这里是文档http://mono.servicestack.net/docs/text-serializers/json-serializer,这里是基准测试http://mono.servicestack.net/benchmarks/
发布于 2013-05-24 20:26:02
这可能不是您正在寻找的答案,但它可能会有所帮助。尝试让控制器方法接受签名中的模型并使用Ajax.BeginForm(),而不是使用FormCollection。这将消除序列化的需要,并允许MVC完成它的工作。另外,有一个带有问题类型列表的模型可能值得研究一下。这种方法似乎也消除了遍历post上的值的需要,因为它们已经在模型中了。
发布于 2014-03-11 18:25:55
我没有尝试过,但是当我使用整数索引时,绑定器在绑定到IEnumerable时没有任何问题。因为您实际上并没有使用这些Guids,所以我将它们替换为整数。(0,1,2...)
我猜您可以在呈现表单的页面上或使用JS轻松完成此操作。
https://stackoverflow.com/questions/14961290
复制相似问题