2014-12-27 20 views
6

我有一個相當簡單的Web API應用程序,目前有一個路線設置。如果用戶嘗試訪問任何其他路由,他們將獲得404回來,但404的主體是HTML而不是JSON(這是它們的接受頭要求的內容)。什麼是最簡單(至少代碼/配置添加到我的項目)的方式讓IIS響應與JSON錯誤響應而不是網頁的不存在路由的請求?如何在WebAPI中返回404s和403s的json?

同樣的問題適用於403s。如果我嘗試導航到我的應用程序的根目錄,則會返回403,再次作爲網頁。我寧願這是一個404,但更大的問題是我如何使所有來自我的應用程序的響應是JSON而不是僅在有效路由上的響應?我提到了403,因爲我正在尋找一個更廣泛的解決方案,而不是僅僅建立一條全面的路線,因爲我不相信這會幫助我解決控制器操作之外發生的403或任何其他隨機異常。

最好,我希望我的應用程序尊重請求上的accept頭。然而,由於我的API現在只支持JSON,我願意與(暫時)共處,它總是以JSON響應。

我正在使用WebAPI 2.2和.NET 4.5.2。

編輯

這不是一個格式化的問題。格式化程序正確地應用於成功的消息,並遵循請求中的accept頭。這特別是未處理的路由和Web服務器錯誤的問題(如嘗試訪問Web根目錄時被禁止)。

編輯2

重現步驟:

  1. 打開Visual Studio 2013更新4
  2. 新建項目
  3. 選擇的.NET Framework 4.5.2
  4. 選擇模板> Visual C#> Web> ASP.NET Web應用程序
  5. 選擇「空」,將所有文件夾和核心參考取消選中
  6. 右鍵單擊項目>添加>新建腳手架項目> Web API 2控制器 - 清空
  7. 修改DefaultController,如下所示。
  8. 修改WebApiConfig.cs,如下所示。
  9. 運行/調試

我想到的是,當我瀏覽到http://localhost:<port>/api/do_stuff我看到Success!在根據接受頭(這是我做的),XML或JSON,當我瀏覽到任何其他網頁,我應該看到Failure!(我沒有)。相反,當我導航到任何其他頁面時,我看到IIS的404響應。

DefaultController.cs:

[RoutePrefix("api")] 
public class DefaultController : ApiController 
{ 
    [HttpGet] 
    [Route("do_stuff")] 
    public String DoStuff() 
    { 
     return "Success!"; 
    } 
} 

WebApiConfig。CS:

public static class WebApiConfig 
{ 
    public static void Register(HttpConfiguration config) 
    { 
     config.MapHttpAttributeRoutes(); 
     config.Filters.Add(new CustomExceptionFilter()); 
    } 

    private class CustomExceptionFilter : ExceptionFilterAttribute 
    { 
     public override void OnException(HttpActionExecutedContext actionExecutedContext) 
     { 
      if (actionExecutedContext.Response.StatusCode == System.Net.HttpStatusCode.NotFound) 
      { 
       actionExecutedContext.Response = new System.Net.Http.HttpResponseMessage(System.Net.HttpStatusCode.NotFound) 
       { 
        Content = new StringContent(@"""Failure!"""), 
       }; 
      } 
     } 
    } 
} 

編輯3

我也試圖加入一個全球性的異常處理程序和異常記錄如下所示: http://www.asp.net/web-api/overview/error-handling/web-api-global-error-handling

無論是當我嘗試瀏覽到一個無效的被稱爲在上例中路由或導航到站點根目錄。

+0

如果接受頭部是text/html的,而不是應用/ JSON然後返回HTML可能是無論如何做正確的事情。 –

+0

我不認爲這個答案在這裏適用,因爲接受頭文件當前被設置爲application/json,但是我得到的是text/html。這意味着我的格式化程序不會因缺少路由和禁止請求而受到尊重。 –

+0

雖然我會檢查你提到的步驟並回復,但是你可以使CustomExceptionFilter成爲一個獨立的公共類,使它成爲一個私有類有什麼意義,我的理解是即使你已經註冊了,它只會用於異常內WebAPIConfig,這就是爲什麼它沒有觸發任何遇到的異常 –

回答

-1

呼叫從自己的計劃包羅萬象的路線返回一個jsonResult行動像下面的功能如下

public JsonResult Handle404() 
{ 
    return Json(new { error404 = "NOT FOUND", Message = "Additional Message" }); 
} 

這將產生

var result = 
{ 
    "error404": "NOT FOUND", 
    "Message": "Additional Message" 
}; 

alert(result.error404); 
allert(result.Message); 
+1

catch-all路徑將明確地解決404問題,但是我的應用程序可能拋出的所有其他異常怎麼辦?一個容易重現的例子是當我嘗試訪問我的應用程序的根時得到的403。其他可能包括IIS配置錯誤,應用程序配置錯誤,應用程序崩潰等。據我所知,我可能無法讓IIS返回JSON實現真正致命的錯誤(如內存不足),但我想爲所有可能的JSON響應。 –

0

中的WebAPI創建的異常過濾器和全局應用處理任何種類的.Net或自定義異常。在OnException方法的內部,通過序列化一個對象,如Code Error和Message to Json這樣的對象,將Context類的Response屬性修改爲合適的Json。檢查下列各項link

以下是在我的代碼實現:使用下面的代碼

//創建過濾

public class ViewRExceptionFilterAttribute : ExceptionFilterAttribute 
{ 
public override void OnException(HttpActionExecutedContext context) 
{ 
    context.Response = new HttpResponseMessage 
     { 
      Content = new StringContent(globalHttpContextMessage) 
     }; 
} 
} 

這裏globalHttpContextMessage

globalHttpContextMessage = JsonConvert.SerializeObject(exceptionMessageUI, Formatting.Indented); 

異常消息UI架構如下:

[JsonObject] 
    public class ExceptionMessageUI 
    { 
     /// <summary> 
     /// 
     /// </summary> 
     public int ErrorCode { get; set; } 

     /// <summary> 
     /// 
     /// </summary> 
     public string ErrorMessage { get; set; } 
    } 

//註冊過濾

public static class WebApiConfig 
    { 
     public static void Register(HttpConfiguration config) 
     { 
      config.Filters.Add(new ViewRExceptionFilterAttribute()); 
     } 
    } 
+0

我添加了一個異常過濾器,並在OnException中放置了一個斷點,並且它似乎沒有被擊中。我目前運行在IISExpress進行調試,我還沒有嘗試過在完整的IIS中,但理想情況下,我想要一個無論託管方法如何的解決方案。 –

+0

當IIS託管時,它似乎沒有被擊中。 –

+0

這很奇怪,它適用於我每次和所有主機場景包括Visual Studio開發Web服務器,只有我能想到的原因是未註冊的過濾器或應用於類型來截取和修改上下文響應。請檢查或列出您到目前爲止所採取的步驟。通常情況下,Globa.asax.cs中的註冊可能無法在最新版本中使用。我希望你已經查看了上面粘貼的鏈接的詳細信息: http://www.asp.net/web-api/overview/error-handling/exception-handling –