vot*_*ive 14 asp.net-mvc iis-7 json asp.net-web-api asp.net-identity-2
我有一个ASP.net MVC 5项目,其中包含特定"API"区域中的WebAPI.我在我的web.config中启用了IIS7错误处理,如下所示:
<system.webServer>
<httpErrors errorMode="Custom" existingResponse="Replace">
<remove statusCode="400" subStatusCode="-1" />
<remove statusCode="404" subStatusCode="-1" />
<remove statusCode="500" subStatusCode="-1" />
<error statusCode="400" path="400.html" responseMode="File" />
<error statusCode="404" path="404.html" responseMode="File" />
<error statusCode="500" path="500.html" responseMode="File" />
</httpErrors>
</system.webServer>
Run Code Online (Sandbox Code Playgroud)
当发生404/500等时,这向MVC网站的用户显示友好消息.当从WebAPI返回特定(合法)状态代码时(例如,调用`/ api/token'时为400),我的问题就出现了.在这些情况下,响应的JSON内容被IIS截获,我的友好消息HTML作为响应返回,而不是来自WebAPI的原始JSON.是否可以从IIS错误处理中排除'API'区域?如果无法做到这一点,那么允许ASP.net MVC网站友好消息和WebAPI JSON响应共存的正确解决方案是什么?
vot*_*ive 13
经过大量的阅读和实验,我发现这种设置组合能够有效地发挥作用:
每个响应状态代码的一个aspx和一个html页面(这是我的):
两个页面之间的唯一区别是aspx页面包含以下行:
<% Response.StatusCode = 500 %>
<% Response.TrySkipIisCustomErrors = true %>
Run Code Online (Sandbox Code Playgroud)
第一行将正确的HTTP状态代码发送回客户端,第二行尝试说服IIS不需要自己处理响应.
自定义错误应该是on,或者remoteonly指向aspx文件:
<customErrors mode="On" defaultRedirect="500.aspx" redirectMode="ResponseRewrite">
<error statusCode="404" redirect="404.aspx" />
</customErrors>
Run Code Online (Sandbox Code Playgroud)
IIS自定义错误也应该打开,并指向该system.webServer部分中的html文件:
<httpErrors errorMode="Custom" existingResponse="Auto">
<remove statusCode="404" subStatusCode="-1" />
<remove statusCode="500" subStatusCode="-1" />
<error statusCode="404" path="404.html" responseMode="File" />
<error statusCode="500" path="500.html" responseMode="File" />
</httpErrors>
Run Code Online (Sandbox Code Playgroud)
该existingResponse="Auto"告诉IIS如果只返回了友好的错误页面SetStatus标志.实际上,这允许ASP.net从该customErrors部分发回自定义响应,自己的自定义错误页面,或允许IIS返回配置的友好错误页面.
默认的ASP.net MVC/WebAPI项目配置了一个HandleErrorAttribute过滤器,用于处理从操作引发的异常并返回正确配置的自定义错误页面.我已经扩展了这个类,通过从这个类派生来处理来自WebAPI操作的异常:
filters.Add(new HandleExceptionAttribute());
Run Code Online (Sandbox Code Playgroud)
public class HandleExceptionAttribute : HandleErrorAttribute
{
public override void OnException(ExceptionContext filterContext)
{
if (filterContext.HttpContext.Request.IsAjaxRequest() && filterContext.Exception != null)
{
filterContext.HttpContext.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
filterContext.HttpContext.Response.StatusDescription = filterContext.Exception.Message;
filterContext.ExceptionHandled = true;
filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;
}
else
{
base.OnException(filterContext);
}
}
}
Run Code Online (Sandbox Code Playgroud)
此类处理来自WebAPI操作的异常,并将异常消息作为JSON响应(具有正确的HTTP状态)返回给调用者.如果您的异常消息不是用户友好的,或者客户端不知道如何解释这些消息,您可能不希望这样做.
| 归档时间: |
|
| 查看次数: |
5433 次 |
| 最近记录: |