2010-04-15 76 views
6

Trong ASP.NET MVC 2, một vài thuộc tính bộ lọc hành động mới đã được giới thiệu, như là "viết tắt" cho các thuộc tính trong ASP.NET MVC 1; ví dụ, việc áp dụng HttpPostAttribute cũng giống như việc áp dụng [AcceptVerbs(HttpVerbs.Post)] cho một phương thức hành động.Các thuộc tính httppost, httpput etc trong ASP.NET MVC 2 hoạt động như thế nào?

Ngoài ra, với cú pháp chi tiết hơn, có thể kết hợp các phương pháp khác nhau, để cho phép ví dụ như cả PostDelete.

Bây giờ tôi tự hỏi: các thuộc tính mới hoạt động như thế nào? Nếu tôi áp dụng cả hai [HttpPost][HttpDelete], thì ASP.NET MVC 2 cho phép cả hai hoặc yêu cầu cả hai (do đó không cho phép gì cả)?

Trả lời

5

Nhìn vào mã cho ActionMethodSelector, có vẻ như tất cả các thuộc tính phương thức hành động phải trả về true cho IsValidForRequest trước khi hành động đó sẽ được thêm vào tập hợp các phương thức khớp có thể. Vì HttpPost và HttpDelete không thể trả về IsValidForRequest cho cùng một yêu cầu, tôi hy vọng rằng việc sử dụng cả hai sẽ ngăn chặn hành động đó từ bao giờ khớp với bất kỳ yêu cầu nào.

Dưới đây là một lời nhận xét kể từ mã:

Danh sách RunSelectionFilters tĩnh tư nhân (...) {
// loại bỏ tất cả các phương pháp mà đang chán bỏ yêu cầu này
// để chọn không tham gia, ít nhất một thuộc tính xác định trên phương pháp này phải trả về false

(tôi nhấn mạnh)

Lưu ý rằng bạn vẫn có thể sử dụng AcceptVerbs và rõ ràng HOẶC động từ nếu bạn cần phải khớp.

EDIT - đây là thuộc tính HttpPostOrDelete cho bạn.

[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)] 
public class HttpPostOrDeleteAttribute : ActionMethodSelectorAttribute 
{ 
    private static readonly AcceptVerbsAttribute _innerPostAttribute = new AcceptVerbsAttribute(HttpVerbs.Post); 
    private static readonly AcceptVerbsAttribute _innerDeleteAttribute = new AcceptVerbsAttribute(HttpVerbs.Delete); 

    public override bool IsValidForRequest(ControllerContext controllerContext, System.Reflection.MethodInfo methodInfo) 
    { 
     return _innerDeleteAttribute.IsValidForRequest(controllerContext, methodInfo) 
       || _innerPostAttribute.IsValidForRequest(controllerContext, methodInfo); 
    } 
} 
+0

Tôi biết tôi vẫn * có thể * sử dụng 'AcceptVerbs', nhưng tôi nghĩ rằng các thuộc tính mới trông đẹp hơn rất nhiều trong mã, và đã hy vọng nhóm MVC đã nghĩ về điều này khi thực hiện ... –

+0

@Tomas - may mắn thay, bạn có thể tự làm cho mình nếu cần. Xem cập nhật của tôi. – tvanfosson

0

Nếu bạn đặt [HttpPost][HttpDelete] cùng nhau, nó sẽ yêu cầu cả hai (điều này là không thể) tôi nghĩ. Nếu bạn chuỗi [HttpGet], nó cũng sẽ không hoạt động, v.v ...

Bạn có thể dễ dàng kiểm tra nó bằng cách chỉ sử dụng phương thức hành động [HttpPost] hiện tại và thêm [HttpDelete] vào đó. Bài đăng sẽ ngừng hoạt động.

Tôi chưa tìm thấy bất kỳ ví dụ nào mà tôi cần phải chuỗi chúng như gợi ý của bạn.

+0

Lý do tôi hỏi là tôi muốn cho phép * cả * POST và DELETE yêu cầu, nhưng không có khác. Tôi đã hy vọng rằng các thuộc tính sẽ hoạt động giống như toán tử UNION set, chứ không phải toán tử INTERSECTION ... Nhưng tốt, bạn không thể luôn có được những gì bạn muốn. Bạn có nguồn gốc về hành vi này ở đâu đó không? –

+0

HttpPost và HttpDelete là khá phổ biến Tôi sẽ mong đợi nếu bạn mong đợi một hành động xóa để hoạt động cả hai bằng cách sử dụng AJAX (Delete) và không AJAX (Post), khi javascript bị vô hiệu hóa. – tvanfosson

+0

Tôi thực sự đã thử nghiệm và không thể tìm thấy bất kỳ kết hợp nào mà tôi có thể nhận được thuộc tính chuỗi như ví dụ của bạn để hoạt động. Tôi đã làm việc phương pháp và chỉ cần thêm thuộc tính cho họ và chắc chắn nó đã phá vỡ tất cả. – Kelsey

4

Tất cả các bộ lọc trong MVC đều không có ngoại lệ - độc lập với nhau. Không có bộ lọc nào được đặt ở bất cứ đâu trong khung MVC. Đây là một quyết định thiết kế có chủ ý để các thành phần khung MVC như người gọi không thể "lừa gạt" và xử lý các bộ lọc nằm trong mã nhị phân MVC khác với bộ lọc mà bạn là nhà phát triển ứng dụng đã viết.

Vì vậy, khi người gọi thấy [HttpGet] và [HttpPost] trên cùng một phương pháp, không có mã đặc biệt nào để lấy liên minh của cả hai. Chúng được thực thi độc lập. Và vì chúng không bao giờ có thể trả về giá trị đúng cho cùng một yêu cầu, [HttpGet, HttpPost] loại bỏ hiệu quả bất kỳ phương thức cụ thể nào khỏi phương thức hành động.

3

Bạn có thể sử dụng AcceptVerbs cho chaining, ví dụ:

[AcceptVerbs(HttpVerbs.Get|HttpVerbs.Post)] 
public ActionResult Customers() { 
} 

hoặc

[AcceptVerbs("GET","POST")] 
public ActionResult Customers() { 
} 
Các vấn đề liên quan