2009-11-05 29 views
9

Tôi đang sử dụng plugin Biểu mẫu JQuery để thực hiện tải lên tệp trên ứng dụng ASP.NET MVC. Tôi đã học được rằng vì một khung nội tuyến được sử dụng để tải lên tệp (chứ không phải là XMLHttpRequest, điều này là không thể), kiểm tra phía máy chủ cho IsAjaxRequest không thành công.Phát hiện IsAjaxRequest() với ASP.NET MVC và Trình tải xuống Tệp JQuery/Tệp JQuery

Tôi đã xem một số bài đăng liên quan đến câu hỏi này nhưng chưa gặp phải bất kỳ giải pháp tốt nào để giải quyết vấn đề này. Như với phần còn lại của ứng dụng của tôi, tôi muốn có thể hỗ trợ cả JavaScript và JavaScript bị vô hiệu hóa kịch bản, đó là lý do tại sao tôi muốn phát hiện xem một yêu cầu là ajax hay không.

Tôi nhận ra rằng phương pháp iframe đang được sử dụng không phải là ajax kỹ thuật, nhưng tôi đang cố gắng bắt chước hiệu ứng ajax.

Mọi đề xuất đều được hoan nghênh.

Trả lời

9

Tôi chỉ nhận ra mình hoàn toàn không trả lời câu hỏi, vì vậy tôi thêm vào phía trên đây, và để lại câu trả lời cũ của tôi dưới đây:

Vấn đề là khi đăng một tập tin trên một iFrame, các Tiêu đề "X-Requested-With" không được đặt và bạn không thể đặt tiêu đề yêu cầu cụ thể cho biểu mẫu POST thông thường trong Javascript. Bạn sẽ phải sử dụng các thủ thuật khác, như gửi một trường ẩn với POST của bạn có chứa một giá trị, sau đó thay đổi hoặc ghi đè phương thức mở rộng "IsAjaxRequest" để kiểm tra điều kiện này. How to override an existing extension method?

Có lẽ lựa chọn tốt nhất có lẽ sẽ là bao gồm phương pháp của riêng mở rộng với một cái tên khác, dựa tắt mặc định MVC phương pháp mã mở rộng với những thay đổi để phát hiện iFrame của bạn tải lên POST, và sau đó sử dụng phương pháp mở rộng của bạn bất cứ nơi nào bạn mong muốn cần nó.


jQuery thực sự đặt 'X-yêu cầu-Với' tiêu đề để 'XMLHttpRequest' theo mặc định. Nó là khá hữu ích miễn là bạn cẩn thận để làm tất cả các cuộc gọi AJAX của bạn trên jQuery.

Tùy thuộc vào nhu cầu của bạn, thật dễ dàng để thiết lập việc phát hiện trong một bộ lọc hành động để sử dụng nó khi cần thiết, hoặc thậm chí xây dựng nó thành một lớp điều khiển như vậy:

[jQueryPartial] 
public abstract class MyController : Controller 
{ 
    public bool IsAjaxRequest { get; set; } 
} 

Các ActionFilterAttribute:

public class jQueryPartial : ActionFilterAttribute 
{ 
    public override void OnActionExecuting(ActionExecutingContext filterContext) 
    { 
     // Verify if a XMLHttpRequest is fired. 
     // This can be done by checking the X-Requested-With 
     // HTTP header. 
     MyController myController = filterContext.Controller as MyController; 
     if (myController != null) 
     { 
      if (filterContext.HttpContext.Request.Headers["X-Requested-With"] != null 
       && filterContext.HttpContext.Request.Headers["X-Requested-With"] == "XMLHttpRequest") 
      { 
       myController.IsAjaxRequest = true; 
      } 
      else 
      { 
       myController.IsAjaxRequest = false; 
      } 
     } 
    } 
} 

Và bằng cách sử dụng thực hiện:

public class SomeController : MyController 
{ 
    public ActionResult Index() 
    { 
      if (IsAjaxRequest) 
       DoThis(); 
      else 
       DoThat(); 

      return View(); 
    } 
} 
+0

Trong mã của bạn , IsAjaxRequest luôn đúng, đánh bại mục đích của mã .... cộng với đó là chức năng tương tự tồn tại trong phương thức mở rộng ... để thực sự không giúp bạn. – zowens

+1

Cảm ơn thông tin. Theo sau khách hàng tiềm năng của bạn, tôi đã tự động thêm giá trị biểu mẫu ẩn ("isFileUploadAjaxPost") qua JQuery. Trong bộ điều khiển, tôi kiểm tra biến dạng đó. Nếu nó hiện diện, tôi sử dụng TempData để lưu trữ giá trị này trước khi gọi RedirectToAction để hiển thị chế độ xem "chỉnh sửa" cho tệp mới được tải lên. Trong phương thức nhận hành động, tôi kiểm tra cả hai Request.IsAjaxRequest() (như tôi đã làm tất cả cùng) cũng như giá trị TempData của tôi để xác định xem yêu cầu có phải là "ajax" hay không. Hoạt động tuyệt vời. Cảm ơn! – goombaloon

+0

@zowens: Tôi đã sửa mã ngay bây giờ, nhưng có, tôi nhận ra sau khi thực hiện và sau đó xem xét phương pháp mở rộng IsAjaxRequest giống hệt nhau. Tôi đã điều chỉnh mã từ một ActionFilter tự động đặt trang cái dựa trên kiểu yêu cầu mà tất nhiên là phần nào ít dư thừa hơn so với mã trên. – Jay

11

Bạn cần đặt tiêu đề "X-Requested-With" cho phương thức IsAjaxRequest để trả về true. Đây là cách bạn làm điều đó trong jquery.

$(document).ready(function() { 
    jQuery.ajaxSetup({ 
      beforeSend: function (xhr) { 
       xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest'); 
       return xhr; 
      } 
    }); 
}); 
+0

Plugin Biểu mẫu JQuery không sử dụng XMLHttpRequest để tải tệp lên. Nó sử dụng iframe. – goombaloon

+0

Điều này có thể là câu trả lời hoàn hảo, nếu nó hoạt động ... –

+1

làm việc cho tôi trong góc '$ httpProvider.defaults.headers.common = {'X-Requested-With': 'XMLHttpRequest'}; ' – parliament

2

tôi chỉ cần stumbled acr oss câu hỏi này và sau đó tìm thấy giải pháp tốt hơn, do đó, đây là (cho tất cả mọi người nhận được ở đây từ google):

Plugin biểu mẫu jQuery có hai tùy chọn có thể trợ giúp trong trường hợp này.

  1. nếu bạn đang sử dụng yêu cầu đăng, có vẻ như nó luôn sử dụng khung nội tuyến, vì vậy nếu bạn không cần tải lên tệp, hãy đặt iframe = false trong tùy chọn Biểu mẫu được trợ giúp trong trường hợp của tôi.

  2. Nếu bạn cần iframe cho fileuploads, bạn có thể sử dụng tài sản dữ liệu trong những lựa chọn để đánh lừa các

    IsAjaxRequest() setting : data: { "X-Requested-With": "XMLHttpRequest" }

Full kịch bản với cả hai lựa chọn trông như thế:

$('#someform').ajaxForm(
{ 
     dataType: 'json', 
     success: onSuccess, 
     error: onError, 
       iframe: false 
     data: { "X-Requested-With": "XMLHttpRequest" } 
    } 
); 
11

Kể từ ASP.NET MVC 2 (và trở đi) có một phương pháp mở rộng trên Request.

if (Request.IsAjaxRequest()) 
{ 
    // was an ajax request 
} 

Sử dụng một phương pháp jQuery như .load() trên một phương pháp điều khiển sẽ cho kết quả Request.IsAjaxRequest() trở thành sự thật.

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