2013-09-10 50 views
10

使用ASP.NET MVC 5,我想爲不同的場景返回適當的HTTP狀態碼(401用戶沒有被認證,403用戶沒有權限某些資源,等等),而不是在jQuery中處理它們。HttpStatusCodeResult(401)返回「302 Found」

但問題是,當我嘗試返回401時,它總是返回「302:找到」。自定義狀態碼的訣竅是什麼?爲什麼這不起作用?

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

    // ... other code ... 
} 

編輯1:有趣的一點:

如果我有404這樣的替換401:

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

然後,它確實給了404和jQuery能趕上問題。然而,它不是一個優雅的解決方案,因爲錯誤代碼是不同的。

編輯2: 302是對我不好,因爲結果將在jQuery.get().fail()使用,但302不會通過靶向fail()

+0

您使用表單身份驗證嗎? –

+0

看看這個:http://stackoverflow.com/questions/10348111/custom-error-message-with-httpstatuscoderesult-jquery – mrtig

+0

mrtig:我以前見過這個,但沒有幫助,因爲它說它已經解決了通過使用IIS express。我使用IIS Express,但我仍然有問題。 –

回答

18

大聲笑,這是一個真棒問題

的方式權威性作品在MVC中,當你沒有登錄並嘗試訪問一個安全頁面時,它會拋出一個401異常。 MVC然後捕獲該異常,並且用戶的登錄頁面(這是302,你所看到的)

我想有一些事情你可以做些什麼來解決它重定向:

編輯

根據您的意見,以下代碼將通過ajax請求時將所有重定向轉換爲401s。這是避免列出的問題的一種方法

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

重定向不會發生,因爲控制器的方法是通過AJAX調用的,這就是爲什麼我需要而不是302,所以'jQuery.get'可以識別它。 –

+1

@ user2270404看看phil haacks的代碼。他創建了一個HTTP模塊來排序這個問題,並返回一個401(完全是ajax的情況)它有點混亂,但它應該解決你的問題。根據文章,如果你使用.NET 4.5的東西,還有更好的方法來解決這個問題。 –

+0

我檢查過這篇文章,它有點混亂。我正在使用.NET 4.5.1並檢查了4.5解決方案,但是我還沒有找到一種方法來處理返回ActionResult的方法中的'HttpResponse.SuppressFormsAuthenticationRedirect'屬性。 然而,我發現了以下駭客評論:它有一點點補充:https:// gist。github.com/1264267 如果您包含此代碼段,我將很樂意接受您的回答。再次感謝你。 –