在ASP.Net MVC 3中处理Ajax调用的正确方法

在ASP.Net MVC中编写Ajax调用时,就发出调用,在服务器上处理它们以及处理客户端上的成功和失败而言,我们有很多选择。 有些事情显然有正确的答案,但我一直无法找到明确的指导。 那么,端到端,进行ajax调用的正确方法是什么?

包含

  • 将url的动作url注入ajax调用的最佳方法是什么?
  • 选择JsonBehavior时有哪些注意事项?
  • 在服务器端处理错误的最佳方法是什么?
    • 客户端错误()回调是由任何错误(即意外的OutOfMemoryException)触发,还是仅由可预见的错误(即无效输入)触发?
    • 以错误()回调将被触发的方式导出错误的最佳方法是什么。
    • 确保错误回调的最佳方法是获取正确的状态代码和响应文本。
    • validation错误是否会导致Error StatusCode,或者它们是否应成为响应validation对象的一部分。
  • 在客户端处理错误的最佳方法是什么?
    • 是否应以与validation摘要类似的方式显示服务器端的意外错误? 也许只是一个“错误的东西”对话框? 客户应该能够区分这两者吗?

人们对此有何看法?

问/答风格

将URL操作的URL注入Ajax调用的最佳方法是什么?
没有关于此的约定,这在很大程度上取决于您的内容如何被带到客户端。 是通过视图/部分视图(在这种情况下,您可以使用Html / Url帮助器方法生成URL,或者它是纯粹在客户端生成的url(模板等)。我们只是希望使用Ajax扩展一些常用的HTML元素,这很常见行为(如表单,按钮和链接)。在这种情况下,最好提供正确的URL,我们也可以从中读取它们并在我们的脚本中使用它们(如链接中的href )。对于用户指向的东西,它也更清晰我们是否将它们转换为GET / POST / DELETE / PUT请求并不重要。我建议避免在脚本中硬编码URL,因为您可能会更改路由或提供其他处理方式。使用Html帮助程序尽可能在维护方面是一种更好的方法。当向不自动支持它们的元素添加URL(没有hrefsrc属性)时,您总是可以将它们添加为自定义属性,尤其是在使用数据属性时(如data-href或者类似的。)读约翰 Resig关于这些的博客文章 。

选择JsonBehavior时有哪些注意事项?
当你必须返回Json时,最好发出POST请求。 在GET请求中,您必须了解JSON Hijacking可能带来的影响,这也是您必须明确指定允许使用JSON结果获取请求的原因。

在服务器端处理错误的最佳方法是什么?
处理服务器错误(不能也不应该被抑制)的最佳方法是实际通知用户错误。 它的细节通常并不重要,因为用户不是精通开发人员,但告诉他们出了问题是可以的。 特别是如果你能为他们提供某种解决方案。 并且使用Ajax调用它可以将错误返回为可以使用error handling程序Javascript函数处理的错误。 我写了一篇博文,详细介绍了整个过程 ,并提供了显示如何正确处理validation错误的代码。 我个人认为将错误视为成功是错误的。 因此,我没有。 但这是有争议的。 我使用的代码相当简化了我的控制器操作:

 [HandleModelStateException] public ActionResult AddUser(User user) { if (!this.ModelState.IsValid) { throw new ModelStateException(this.ModelState); } // process valid data } 

客户端错误()回调是由任何错误(即意外的OutOfMemoryException )触发,还是仅由可预见的错误(即无效输入)触发?
如前所述,当用户从他们发起的内容中获得意外结果时,应向用户报告错误。 不要压制应该向他们报告的错误。 但是不要过多详细说明。 内存不足exception有点太复杂,无法解释通常的计算机用户。 报告一些人性化和简短的事情。

error()回调将被触发的方式导出错误的最佳方法是什么。
查看我的博客文章并检查代码,了解如何创建由error()函数处理的error()

确保错误回调的最佳方法是获取正确的状态代码和响应文本。
相同的博文

validation错误是否会导致错误StatusCode或者它们是否应成为响应validation对象的一部分。
validation错误本质上是警告,应该这样对待。 这就是为什么你可以在某些网站上看到积极的表单validation模式,这些模式也会在数据有效时报告,而不是仅通知用户他们已经犯了另一个错误。 validation错误通常源于无效的用户界面体验和信息不足。

在客户端处理错误的最佳方法是什么?
这在很大程度上取决于您的应用程序,但我建议您遵循经过validation的模式,因为用户可能知道演练并且不会混淆它们。 为什么您认为OpenOffice使用与Microsoft Office几乎相同的UI? 因为用户知道它是如何工作的,所以它更有可能快速,轻松地熟悉应用程序。 但如果可以的话,不要将用户视为愚蠢的人。 使用肯定validation。 某些错误也应显示为错误。 哦。 顺便说一句。 我在我的应用程序中使用不显眼的信息,其中向用户报告成功操作等信息但不干扰他们的工作。 它会在一段时间后自动消失。 与GMail的相似。 它只是通知您已发送邮件,此信息不需要任何确认。
jQuery ajax() functin支持成功和错误函数,因此使用它们是明智的。 再说一次:因为成功回归错误是不对的。 我们不需要错误function。 我的HandleModelState操作filter返回错误,其中包含可以使用的特定400错误代码及其结果。

 $.ajax({ url: $(this).attr("href"), data: someDataObj, type: "POST", success: function(data){ // process data }, error: function(xhr, status, err){ if (xhr.status = 400) { // handle my error in xhr.resposeText } else { // handle other errors that are cause by unknown processing } } }); 

是否应以与validation摘要类似的方式显示服务器端的意外错误? 也许只是一个“ 错误的东西 ”对话框? 客户应该能够区分这两者吗?
人们不喜欢大红色警报。 如果某些内容本质上是警告,则应该比实际错误更友好地处理,以防止您的应用正常工作。 特别是validation应该非常友好。 错误应该由用户确认,警告可能不应该。 取决于他们的性质。 但如果他们应该那么他们可能就是错误。

我希望这能为你解决一些问题。

将url的动作url注入ajax调用的最佳方法是什么?

就个人而言,我在AJAX的DOM元素上使用HTML5 data- *属性。 例如:

 
Foo Bar

然后:

 $('#foo').click(function() { var url = $(this).data('url'); // TODO: perform the AJAX call }); 

当然,如果DOM元素表示锚或表单,我将使用本机属性(action或href)。

选择JsonBehavior时有哪些注意事项?

没有具体考虑。 请记住,客户端浏览器可能会缓存GET请求,因此您可能需要在客户端上指定{ cache: false } 。 哦,当然还有Json服务器上的AllowGet。

在服务器端处理错误的最佳方法是什么?

我个人使用FluentValidation.NET来处理我的视图模型上的validation错误。 服务层也可能存在错误。

在客户端处理错误的最佳方法是什么?

如果服务器返回JSON,我通常有一个看起来如下的结构:

 { error = 'some error message', result: null } 

要么:

 { error = null, result: { foo: 'bar' } } 

取决于是否有错误,并在客户端:

 success: function(data) { if (data.error != null && data.error != '') { // error } else { // use data.result } } 

我对服务器上未处理的exception的所有内容使用error回调,在这种情况下只显示一些通用错误消息。 可以使用$.ajaxSetup指定全局error handling程序。

为了简化在服务器上生成这些JSON结果并干扰我的操作,我使用自定义操作filter来测试请求是否是AJAX请求,以及是否是AJAX请求测试是否有添加到ModelState的validation错误以及是否用自定义错误JsonResult替换动作结果以处理错误情况。

以下是我在最近的一些项目中的工作方式:

1)我在视图中使用Url.Action调用注入ajax url。

2)Jqgrid使用GET来获取网格数据,因此在填充网格控制器操作中,我需要在Json方法调用中使用JsonRequestBehavior.AllowGet开关。

3)我最近切换到了微软不引人注意的客户端validation,它有一个简洁的ModelState.IsValid方法,您可以在控制器操作中运行服务器端,以确保在服务器端也运行相同的确切validation而无需重复代码。 它花了一些工作将它与jquery.maskedinput进行网格划分等等来掩盖/取消屏蔽数据, 这里是关于如何使所有这些工作的文章 。

4)关于显示错误客户端,这是一个必须由利益相关者充实的设计问题。 就个人而言,我不喜欢文本框旁边的validation或页面顶部的validation摘要。 我更喜欢错误跳出你的脸,因此我调整了微软的jquery.validate.unobtrusive.js以在弹出模式对话框中显示错误。 您可以在jquery.validate.unobtrusive.MOD.js文件中看到上面解决方案中的代码(注意我的版本后缀为“.mod.js”),您可以在Site.Master中看到错误对话框。

控制器动作示例:

 [HttpPost] public ActionResult Index(PersonalInformation model) { if (ModelState.IsValid) { // TODO: sell personal information to sleazeballs TempData["PersonalInformation"] = model; return RedirectToAction("Success"); } // If we got this far, something failed, redisplay form Index_Load(); return View(model); } 

希望这可以帮助,

罗伯特