2013-09-10 38 views
10

Sử dụng ASP.NET MVC 5, tôi muốn trả lại mã trạng thái HTTP thích hợp cho các trường hợp khác nhau (401 cho người dùng không được xác thực, 403 khi người dùng không có quyền đối với một số tài nguyên, v.v. .), hơn là xử lý chúng trong jQuery.HttpStatusCodeResult (401) trả về "302 Tìm thấy"

Nhưng vấn đề là, khi tôi cố gắng trả lại 401, nó luôn trả về "302: Found". Bí quyết cho mã trạng thái tùy chỉnh là gì và tại sao điều này không hoạt động?

public ActionResult My() 
{ 
    if (User.Identity.IsAuthenticated == false) 
    { 
     return new HttpStatusCodeResult(401, "User is not authenticated."); 
      // Returns "302: Found" 
    } 

    // ... other code ... 
} 

EDIT 1: Thú vị bit:

Nếu tôi thay thế 401 với 404 như thế này:

return new HttpNotFoundResult("User is not authenticated."); 

Sau đó, nó thực sự mang đến cho 404 và jQuery có thể nắm bắt được vấn đề. Tuy nhiên nó không phải là một giải pháp thanh lịch vì mã lỗi khác nhau.

EDIT 2: 302 là không tốt đối với tôi, như kết quả sẽ được sử dụng trong jQuery.get().fail(), nhưng 302 sẽ không triger fail()

+0

bạn có đang sử dụng xác thực biểu mẫu không? –

+0

hãy xem xét điều này: http://stackoverflow.com/questions/10348111/custom-error-message-with-httpstatuscoderesult-jquery – mrtig

+0

mrtig: Tôi đã nhìn thấy điều này trước đây, nhưng không giúp ích khi nó nói nó được giải quyết bằng cách sử dụng IIS express. Tôi sử dụng IIS express, vẫn còn tôi có vấn đề. –

Trả lời

18

Lol đây là một vấn đề đáng sợ

Cách công trình auth trong MVC là khi bạn không đăng nhập và cố gắng truy cập một trang bảo mật, nó sẽ ném một ngoại lệ 401. MVC sau đó bắt ngoại lệ này và chuyển hướng người dùng đến trang đăng nhập (được 302 bạn đang nhìn thấy)

Tôi cho rằng có một vài điều bạn có thể làm để sửa chữa nó:

EDIT

Theo nhận xét của bạn, đoạn mã sau sẽ chuyển tất cả chuyển hướng thành 401 khi được yêu cầu qua ajax. Đây là một cách tiếp cận để tránh sự cố được liệt kê

public class MvcApplication : HttpApplication { 
    protected void Application_EndRequest() { 
     var context = new HttpContextWrapper(Context); 
     // If we're an ajax request, and doing a 302, then we actually need to do a 401 
     if (Context.Response.StatusCode == 302 && context.Request.IsAjaxRequest()) { 
      Context.Response.Clear(); 
      Context.Response.StatusCode = 401; 
     } 
    } 
} 
+0

Chuyển hướng sẽ không xảy ra, vì phương thức của controller được gọi thông qua AJAX, đó là lý do tại sao tôi cần một cái gì đó khác hơn 302, vì vậy 'jQuery.get' có thể nhận ra nó. –

+1

@ user2270404 hãy xem mã phil haacks xung quanh việc này. Ông tạo ra một mô-đun HTTP để sắp xếp vấn đề này ra và trả lại một 401 anyway (cho chính xác trường hợp ajax) của nó một chút lộn xộn nhưng nó nên sắp xếp ra vấn đề của bạn. Theo bài viết đó cũng là một cách tốt hơn để có được xung quanh này nếu bạn đang sử dụng. NET 4.5 thứ –

+0

Tôi đã kiểm tra bài viết, đó là một chút lộn xộn. Tôi đang sử dụng .NET 4.5.1 và kiểm tra các giải pháp 4,5 nhưng tôi đã không tìm thấy một cách để thao tác 'HttpResponse.SuppressFormsAuthenticationRedirect' tài sản từ phương pháp của tôi mà trả về một' ActionResult'. Tuy nhiên tôi tìm thấy sau đây trong số các bình luận haack: nó khá có thể sử dụng với một chút bổ sung: https: // gist.github.com/1264267 Nếu bạn bao gồm đoạn mã này, tôi sẽ sẵn lòng chấp nhận câu trả lời của bạn. Cám ơn bạn một lần nữa. –

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