2012-03-02 19 views
7

Tôi muốn có thể đánh dấu một hành động trên bộ điều khiển được gọi là cả từ các cuộc gọi ajax và qua RenderAction. Vấn đề là cả hai thuộc tính này lấy được hoặc thực hiện các trừu tượng khác nhau. Một đường ra là tiếp theo:Kết hợp AjaxOnlyAttribute và ChildActionOnlyAttribute vào một bộ lọc hành động

[AjaxOnly] 
PartialViewResult GetViewAjax(int foo) { return GetView(foo); } 
[ChildActionOnly] 
PartialViewResult GetView(int foo) { ... } 

Nhưng điều này không hề gọn gàng chút nào.


Các AjaxOnly thuộc tính tôi đang nói về là:

public sealed class AjaxOnlyAttribute : ActionFilterAttribute 
{ 
    #region Public members 

    public override void OnActionExecuting(ActionExecutingContext filterContext) 
    { 
     if (filterContext == null) 
      throw new ArgumentNullException("filterContext"); 
     if (filterContext.HttpContext.Request.Headers["X-Requested-With"] != "XMLHttpRequest") 
      filterContext.Result = new HttpNotFoundResult(); 
    } 

    #endregion 
} 

Phương pháp này được lấy từ MVC3 tương lai. Một bình luận quan trọng tại sao tình trạng này không được filterContext.HttpContext.Request.IsAjaxRequest() được thực hiện bởi nhóm phát triển và cho biết như sau:

// Dev10 #939671 - If this attribute is going to say AJAX *only*, then we need to check the header 
// specifically, as otherwise clients can modify the form or query string to contain the name/value 
// pair we're looking for. 

Trả lời

16

này không thực hiện bất kỳ ý nghĩa. Hai thuộc tính này là loại trừ lẫn nhau. Nếu một hành động được đánh dấu bằng [ChildActionOnly] nó không bao giờ có thể được truy cập trực tiếp bởi máy khách bằng cách sử dụng một yêu cầu HTTP (có thể là đồng bộ hoặc không đồng bộ). Vì vậy, nếu bạn muốn một hành động có thể truy cập được bằng AJAX, bạn không bao giờ nên trang trí nó với thuộc tính [ChildActionOnly].

Tôi không biết [AjaxOnly] thuộc tính này là gì và nơi nó xuất phát từ nhưng tùy thuộc vào cách nó được thực hiện bạn có thể cần phải tinh chỉnh nó để cho phép các yêu cầu hành động con nếu nó chỉ dựa vào phương pháp Request.IsAjaxRequest(). Ví dụ, nếu nó là một cái gì đó như thế này:

public class AjaxOnlyAttribute : ActionFilterAttribute 
{ 
    public override void OnActionExecuting(ActionExecutingContext filterContext) 
    { 
     if (!filterContext.HttpContext.Request.IsAjaxRequest()) 
     { 
      filterContext.Result = new HttpNotFoundResult(); 
     } 
    } 
} 

bạn có thể muốn tinh chỉnh nó như thế này:

public class AjaxOrChildActionOnlyAttribute : ActionFilterAttribute 
{ 
    public override void OnActionExecuting(ActionExecutingContext filterContext) 
    { 
     if (!filterContext.HttpContext.Request.IsAjaxRequest() && 
      !filterContext.IsChildAction 
     ) 
     { 
      filterContext.Result = new HttpNotFoundResult(); 
     } 
    } 
} 
+0

Tại sao? Giả sử hành động của bạn được tái sử dụng từ các vị trí khác nhau thông qua các yêu cầu RenderAction() và ajax. Giả sử chúng được tái sử dụng trên các trang khác nhau như smth vẽ một số bảng công cụ tiêu chuẩn cho nhiều nơi và được sử dụng hơi khác nhau trong các ngữ cảnh khác nhau –

+0

@Hohhi, vì vậy bạn muốn hành động của mình chỉ có thể truy cập được thông qua cuộc gọi AJAX hoặc dưới dạng Hành động con ? –

+0

Chính xác, Cảm ơn bạn đã đề xuất, tôi sẽ cập nhật câu hỏi và cho biết tôi nhận được bao lâu trong một khoảng thời gian –

1

Lấy cảm hứng về câu trả lời Darin và mã nguồn ChildActionOnlyAttribute 's, đây là giải pháp tôi đã đến với, mà tôi nghĩ đó là một chút nhỏ hơn:

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)] 
public class AjaxOrChildAttribute : ActionMethodSelectorAttribute 
{ 
    public override bool IsValidForRequest(ControllerContext controllerContext, System.Reflection.MethodInfo methodInfo) 
    { 
     return controllerContext.IsChildAction || controllerContext.RequestContext.HttpContext.Request.IsAjaxRequest(); 
    } 
} 

bằng cách này, việc phê chuẩn được thực hiện trước khi thậm chí cố gắng để thực hiện, và các lỗi mà bạn nhận được nếu bạn gõ vào url là chính xác sam e như thử bất kỳ url không hợp lệ nào.

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