我正在为一位同事审查一些代码,虽然我正在查看的jQuery Ajax调用没有任何内在的错误的,但我想更加确定应该和不应该出现的内容在对ASP.Net MVC控制器操作的正常Ajax调用中。
例如,在以下代码中:
$(function() {
$.ajax({
url: "/Controller/action",
type: "POST",
data: ({ myObjectOrParameters }),
success: function(data) { alert(data); }
});
});
这种模式是否正常,还是还有其他东西应该存在? contentType
是否可取?那么dataFilter
呢?这是不必要的,因为我们不使用Microsoft Ajax并且不关心它返回的“.d”,我是否应该担心?
type
怎么样?最佳做法是在阅读或更新信息时使用“GET”甚至“PUT”,还是在每种情况下最适合使用“POST”?
在每种情况下使用$.ajaxSetup
更合适,还是我们每次都能明确定义我们的参数?
答案 0 :(得分:6)
我更希望看到本案例中使用的$.post()
方法。除非您在$.ajax()
中使用更深奥的选项,否则当有更短且更简洁的方法时,我认为没有任何理由使用它:
$.post("/Controller/action", { myObjectOrParameters }, function(data) {
alert(data);
});
答案 1 :(得分:5)
如前所述,您提出的请求类型取决于要采取的行动类型。
是其他类型的请求HEAD,DELETE等。但是,这些在RESTful开发之外并不常用(http://en.wikipedia.org/wiki/Representational_State_Transfer)。
我在开发依赖于javascript / ajax的网站时一直使用的做法是在jQuery之上为网站开发自定义javascript框架。该库将处理特定于网站的常用功能。例如,你的问题是关于jQuery的ajax函数。特定于您的网站的一些常见功能可能是:显示错误消息,处理意外错误代码(500,404等),向调用添加公共参数以及数据传输类型(JSON,XML等)。
网站的简单自定义JavaScript框架可能如下所示:
(function ($) {
if (!window.myWebsite) { window.myWebsite = {}; }
// once myWebsite is defined in the "window" scope, you don't have
// to use window to call it again.
$.extend(myWebsite, {
get: function (url, data, callback) {
myWebsite._ajax(url, data, "GET", callback);
},
post: function (url, data, callback) {
myWebsite._ajax(url, data, "POST", callback);
},
_ajax: function (url, data, type, callback) {
// http://api.jquery.com/jQuery.ajax/
$.ajax({
type: type,
url: url,
data: data,
dataType: 'json',
success: function(data, status, request) {
// I'll talk about this later. But, I'm assuming that the data
// object returned from the server will include these fields.
if( data.result == 'error' ) {
myWebsite._displayError( data.message );
}
// if no error occured then the normal callback can be called
if( $.isFunction(callback) )
callback();
},
error: function (request, status, error) {
myWebsite._displayError( error );
// you can also use this common code for handling different
// error response types. For example, you can handle a
// 500 "internal server error" differently from a 404
// "page not found"
}
});
},
_displayError: function( text ) {
// Many pages have a common area
// defined to display error text, let's call that
// area <div id="errorDiv" /> on your website
$('#errorDiv').text(error);
}
});
})(jQuery);
您可以从页面调用自定义javascript,如下所示:
myWebsite.get( '/Controller/Action', {}, function() { ... } );
一旦你有了基本的javascript框架,你就可以在ASP.NET MVC项目中添加类,这将返回框架所期望的数据。在上面的javascript中,_ajax函数有一个成功函数,它需要一个包含属性'result'和'message'的JSON对象。这可以通过MVC模型中的基类来实现。
using System;
/// <summary>
/// <para>
/// Encapsulates the common/expected properties for the JSON results
/// on this website.
/// </para>
/// <para>
/// The <see cref="result" /> property should contain the value 'success', when
/// all processing has gone well. If the action has either 'fail'ed or has an 'error'
/// then the <see cref="message"/> property should also be filled in.
/// </para>
/// </summary>
public abstract class JsonResultBase
{
#region constructors
/// <summary>
/// Creates a basic <see cref="JsonResultBase"/> with a 'success' message.
/// </summary>
public JsonResultBase()
: this("success", string.Empty) { }
/// <summary>
/// Creates a <see cref="JsonResultBase"/> with the <see cref="result"/> and <see cref="message"/>
/// properties initialized. This should be used when creating a 'fail'
/// result.
/// </summary>
/// <param name="result">The result type: 'sucess', 'fail', or 'error'.</param>
/// <param name="message">The message which described why the result occured.</param>
public JsonResultBase(string result, string message)
{
if (result != "success" && string.IsNullOrEmpty(message))
{
throw new ArgumentException("message", "message must have a value when the result is not 'success'.");
}
this.result = result;
this.message = message;
}
/// <summary>
/// Creats a <see cref="JsonResultBase"/> which translates an exception into
/// an error message for display on the webpage.
/// </summary>
/// <param name="e">The exception to send back.</param>
public JsonResultBase(Exception e)
{
this.result = "error";
this.message = e.Message;
}
#endregion
#region properties
/// <summary>
/// The result of the action. This could contain the value of 'success', 'fail', or 'error'.
/// Or, some other values that you define.
/// </summary>
public string result { get; set; }
/// <summary>
/// Any extra information which would be helpful to describe a result. This will always be
/// populated if the result is not 'success'.
/// </summary>
public string message { get; set; }
#endregion
}
然后可以扩展该基类以返回呼叫的特定数据并在控制器中使用。
public class HomeController : Controller
{
private class ValuesJsonResult : JsonResultBase {
public ValuesJsonResult() : base() {}
public ValuesJsonResult(Exception e) : base(e) {}
public string[] values = new string[0];
}
public ActionResult GetList() {
try {
return Json(
new ValuesJsonResult{ values = new [] { "Sao Paulo", "Toronto", "New York" } },
JsonRequestBehavior.AllowGet
);
} catch( Exception e ) {
// Opps, something went wrong
return Json( new ValuesJsonResult(e), JsonRequestBehavior.AllowGet );
}
}
}
HTH
答案 2 :(得分:4)
使用GET进行的请求应该是幂等。(意味着如果重复这些请求,净效果是相同的)。幂等查询的简单子集是没有副作用的查询。例如搜索查询。一个好的经验法则是更新用户状态的事情应该是POST。谷歌有关GET与POST的更多信息。
您缺少的另一个最佳做法是错误处理程序。这会处理500或403服务器错误以响应请求,这是必不可少的。