2008-11-14 29 views
8

Tôi thích sử dụng jQuery với các ứng dụng ASP.NET MVC hơn thư viện Microsoft Ajax. Tôi đã thêm một tham số được gọi là "chế độ" cho các hành động của mình, mà tôi đã đặt trong các cuộc gọi ajax của mình. Nếu nó được cung cấp, tôi trả về một JsonViewResult. Nếu nó không được cung cấp, tôi cho rằng đó là một bài đăng chuẩn của HTTPS và tôi trả về một ViewResult.Có một Request.IsMvcAjaxRequest() tương đương với jQuery không?

Tôi muốn có thể sử dụng một cái gì đó tương tự như IsMvcAjaxRequest trong bộ điều khiển của mình khi sử dụng jQuery để tôi có thể loại bỏ tham số bổ sung trong Tác vụ của mình.

Có điều gì ngoài đó sẽ cung cấp khả năng này trong bộ điều khiển của tôi hoặc một số cách đơn giản để hoàn thành nó không? Tôi không muốn đi viết mã điên vì thêm một tham số hoạt động, nó không phải là lý tưởng.

+0

đối với bất kỳ ai nhầm lẫn IsMvcAjaxRequest hiện đã được đổi tên (như RC1) thành chỉ IsAjaxRequest chỉ để cụ thể làm cho nó tương thích với các thư viện Ajax khác. xin vui lòng xem bài viết của tôi dưới đây –

Trả lời

12

Dưới đây là một ngoại trừ từ release notes MVC RC1 - Jan 2009

đổi tên IsMvcAjaxRequest để IsAjaxRequest

Phương pháp IsMvcAjaxRequest được đổi tên thành IsAjaxRequest. Là một phần của thay đổi này, phương pháp IsAjaxRequest đã được cập nhật để nhận ra tiêu đềX-Yêu cầu-Với HTTP. Đây là tiêu đề nổi tiếng được gửi bởi các thư viện JavaScript chính như Prototype.js, jQuery và Dojo.

Trình trợ giúp ASP.NET AJAX đã được cập nhật để gửi tiêu đề này theo yêu cầu . Tuy nhiên, họ tiếp tục với số cũng gửi nội dung đó vào phần thân của biểu mẫu bài đăng để giải quyết vấn đề tường lửa không rõ tiêu đề .

Nói cách khác - nó được đổi tên cụ thể thành 'tương thích' hơn với các thư viện khác.

Ngoài ra, đối với những ai chưa đọc full release notes nhưng đã sử dụng các phiên bản trước - thậm chí gần đây là phiên bản beta - I STRONGLY khuyên bạn nên đọc chúng đầy đủ. Nó sẽ giúp bạn tiết kiệm thời gian trong tương lai và rất có thể kích thích bạn với một số tính năng mới. Khá đáng ngạc nhiên là có bao nhiêu thứ mới trong đó.

Lưu ý quan trọng: Bạn cần đảm bảo bạn nâng cấp tệp .js cho MicrosoftAjax.MVC (không phải tên chính xác) nếu nâng cấp lên RC1 từ bản Beta - nếu không phương pháp này sẽ không hoạt động. Nó không được liệt kê trong các ghi chú phát hành như là một nhiệm vụ cần thiết để nâng cấp vì vậy đừng quên.

+0

Cảm ơn Simon, hy vọng Andrew Van Slaars sẽ cho bạn câu trả lời được chấp nhận. –

+0

Ngoài ra, đã thay đổi bài đăng của tôi thành cộng đồng wiki trong trường hợp người khác muốn cập nhật câu trả lời "Đã chấp nhận" –

+0

cảm ơn. Tôi chắc chắn câu trả lời của tôi sẽ được lỗi thời một ngày nào đó quá :) tôi đã không ngay cả HEARD của ASP.NET MVC khi bạn đã viết câu trả lời của bạn :) –

4

Xem Simons trả lời dưới đây. Phương pháp tôi mô tả ở đây không còn cần thiết trong phiên bản mới nhất của ASP.NET MVC.

Cách phương pháp mở rộng IsMvcAjaxRequest hiện đang hoạt động là nó kiểm tra Request["__MVCASYNCPOST"] == "true" và chỉ hoạt động khi phương thức là yêu cầu HTTP POST.

Nếu bạn đang thực hiện yêu cầu HTTP POST, bạn có thể chèn động giá trị __MVCASYNCPOST vào yêu cầu của mình và sau đó bạn có thể tận dụng phương pháp mở rộng IsMvcAjaxRequest.

Đây là link to the source of the IsMvcAjaxRequest extension method để thuận tiện cho bạn.

Hoặc, bạn có thể tạo bản sao của phương pháp mở rộng IsMvcAjaxRequest được gọi là IsjQueryAjaxRequest kiểm tra Request["__JQUERYASYNCPOST"] == "true" và bạn có thể chèn động giá trị đó vào POST HTTP.

Cập nhật

tôi quyết định đi trước và cung cấp cho một shot đây là những gì tôi đã đưa ra.

Phương pháp mở rộng

public static class HttpRequestBaseExtensions 
{ 
    public static bool IsjQueryAjaxRequest(this HttpRequestBase request) 
    { 
     if (request == null) 
      throw new ArgumentNullException("request"); 

     return request["__JQUERYASYNCPOST"] == "true"; 
    } 
} 

Kiểm tra từ một hành động nếu một phương pháp là một jQuery $ .ajax() yêu cầu:

if (Request.IsjQueryAjaxRequest()) 
    //some code here 

Javascript

$('form input[type=submit]').click(function(evt) { 
    //intercept submit button and use AJAX instead 
    evt.preventDefault(); 

    $.ajax(
     { 
      type: "POST", 
      url: "<%= Url.Action("Create") %>", 
      dataType: "json", 
      data: { "__JQUERYASYNCPOST": "true" }, 
      success: function(data) {alert(':)');}, 
      error: function(res, textStatus, errorThrown) {alert(':(');} 
     } 
    ); 
}); 
+0

Vì vậy, tôi sẽ vượt qua __JQUERYASYNCPOST giống như bất kỳ tham số khác trong dữ liệu bài của tôi khi sử dụng "$ .post"? Nếu vậy, điều đó sẽ cho tôi cùng một thiết lập cơ bản mà không có tham số phụ, điều này sẽ hoàn hảo. –

+0

Hoàn hảo, cảm ơn! –

+0

Có, chuyển các giá trị trong tham số dữ liệu của $ .post(). Tôi sẽ thử nghiệm đầu tiên với __MVCASYNCPOST để đảm bảo nó hoạt động với các phương pháp mở rộng hiện có. Nếu có thì bạn có thể triển khai phương thức mở rộng của riêng mình và thay đổi nó thành __JQUERYASYNCPOST. –

0

Ok, tôi đã lấy bước này xa hơn và sửa đổi tệp jQuery của tôi để tải thông số bổ sung vào dữ liệu bài đăng, vì vậy tôi không phải lặp lại "__JQUERYASYNCPOST: true" cho mọi cuộc gọi để đăng. Đối với ai đó là quan tâm, đây là những gì định nghĩa mới của tôi với $ .post trông giống như:

post: function(url, data, callback, type) { 
      var postIdentifier = {}; 
      if (jQuery.isFunction(data)) { 
       callback = data; 
       data = {}; 
      } 
      else { 
       postIdentifier = { __JQUERYASYNCPOST: true }; 
       jQuery.extend(data, postIdentifier); 
      } 

      return jQuery.ajax({ 
       type: "POST", 
       url: url, 
       data: data, 
       success: callback, 
       dataType: type 
      }); 
     } 

tôi thêm "postIdentifier" biến cũng như các cuộc gọi đến jQuery.extend. Bây giờ người trợ giúp giải thích trong phản ứng của spoon16 hoạt động mà không cần phải thêm bất kỳ điều đặc biệt nào vào mã jQuery cấp trang của tôi.

+0

... đây là một trong những QA hoàn chỉnh nhất trên SO :) –

+0

Điều gì nếu bạn mở rộng 'ajax()'? Sẽ không tốt hơn khi tất cả các phương pháp khác như 'post()' chỉ gọi qua 'ajax'? –

+0

Tôi có thể đã mở rộng ajax, nhưng mối quan tâm chính của tôi là đăng bài. Thông thường, tôi chỉ sử dụng get cho Ajax nếu nó là một tính năng chỉ có tính năng ajax, chẳng hạn như tra cứu tự động hoàn chỉnh hoặc chức năng tương tự sẽ không có sẵn mà không có ajax, vì vậy đối với những thứ đó, tôi vẫn sử dụng JsonResult. –

3

Tại sao bạn không chỉ đơn giản là kiểm tra "X-yêu cầu-Với" HTTP header gửi tự động bởi hầu hết các thư viện Javascript (như jQuery)?

Nó có giá trị 'XMLHttpRequest' khi một yêu cầu GET hoặc POST được gửi đi.

Để kiểm tra nó, bạn chỉ nên cần phải kiểm tra "Request.Headers" NameValueCollection trong hành động của bạn, đó là:

if (Request.Headers["X-Requested-With"] == "XMLHttpRequest") 
    return Json(...); 
else 
    return View(); 

Bằng cách này, bạn chỉ có thể phân biệt yêu cầu trình duyệt thường xuyên từ các yêu cầu Ajax.

+0

Ý tưởng tuyệt vời. Tôi sẽ không thay đổi câu trả lời của tôi để bạn có thể nhận được càng nhiều đại diện càng tốt :) –

+0

Tôi không biết rằng tiêu đề được yêu cầu có ngay cả ở đó không. Tôi sẽ kiểm tra điều đó và thử nó, có lẽ tôi sẽ cập nhật phương pháp mở rộng để kiểm tra thay vào đó. Bất kỳ ý tưởng tại sao MSFT sẽ không làm điều này để bắt đầu? –

+0

Thực ra, với kiến ​​thức của tôi, thiếu sự tiêu chuẩn hóa về chủ đề này. Tất cả các thư viện xây dựng các tiêu đề của chúng khác nhau (một số chỉ định phiên bản thư viện), nhưng may mắn nhất là đã chấp nhận 'X-Requested-With', tôi không thể biết tại sao Microsoft không có. – Franck

Các vấn đề liên quan