ASP.NET MVC5 删除 API 错误的 html 响应
Posted
技术标签:
【中文标题】ASP.NET MVC5 删除 API 错误的 html 响应【英文标题】:ASP.NET MVC5 remove html response for API errors 【发布时间】:2015-12-14 17:28:43 【问题描述】:我想知道如何更好地解决这个问题。
该应用已注册 mvc web 和 web api。我有一个单独的 mvc web 控制器(称为 Error)负责呈现错误页面。 我的 web.config 看起来像:
<system.webServer>
<httpErrors errorMode="Custom" existingResponse="Replace">
<remove statusCode="404" />
<remove statusCode="500" />
<error statusCode="404" responseMode="ExecuteURL" path="/error/404" />
<error statusCode="500" responseMode="ExecuteURL" path="/error/500/" />
</httpErrors>
</system.webServer>
它适用于 mvc 网页,但现在适用于 web api,当我返回 NotFound() 时,我得到 html 错误页面作为回报。 我想通过使用 location 属性来解决这个问题:
<location path="api">
<system.webServer>
<httpErrors errorMode="Custom" existingResponse="Replace">
<remove statusCode="404" />
<remove statusCode="500" />
</httpErrors>
</system.webServer>
</location>
所以,现在它不返回 html,而只是返回来自 asp.net 的错误字符串。
但是如果我需要从 web api 返回一些对象并在操作中设置错误标头,或者只是没有数据的错误标头?
谢谢
【问题讨论】:
我会看看this question 【参考方案1】:我找到了一种效果很好的解决方案,但我没有对 Web API 端进行任何更改,而是对 MVC Web 进行了更改。
所以在阅读this 之后,我意识到 Web API 异常不会在 global.asax 中处理,为此您需要注册 IExceptionLoggers 或 IExceptionHandler。所以我为解决这个问题所做的是:
-
从 web.config 中删除了问题中提到的设置,并在此处添加了空的
<customErrors mode="On"></customErrors>
。
添加类似于 Global.asax 的内容(基于the article):
protected void Application_Error()
if (Context.IsCustomErrorEnabled)
ShowWebErrorPage(Server.GetLastError());
private void ShowWebErrorPage(Exception exception)
var httpException = exception as HttpException ?? new HttpException(500, "Internal Server Error", exception);
Response.Clear();
var routeData = new RouteData();
// these depend on your Error controller's logic and routing settings
routeData.Values.Add("controller", "Error");
routeData.Values.Add("action", "Index");
routeData.Values.Add("statusCode", httpException.GetHttpCode());
Server.ClearError();
IController controller = new Controllers.ErrorController();
controller.Execute(new RequestContext(new HttpContextWrapper(Context), routeData));
所以这段代码只负责 Mvc 网页。 ErrorController 决定需要渲染什么 View。
Web Api 的默认行为没有改变,因此它像以前一样工作,并且不会呈现任何那些错误的 html 作为响应。他们现在分开了。在我可以手动执行的操作中:
return NotFound();
我看到空的响应正文或用类似的东西控制它
return Request.CreateResponse(HttpStatusCode.BadRequest, error);
【讨论】:
我必须添加 Response.End();在 ShowWebErroPage 方法和 Response.TrySkipIisCustomErrors = true 的末尾;在控制器操作方法中避免来自 IIS 的空白页。【参考方案2】:我不确定这是否正是您想要做的,但如果您只想在错误时发送和对象(json),您可以试试这个。不过,这当然不是最好的出路!
想法是将静态对象作为文本保存在文件中,并在出错时提供文件内容。
为web.config
中的路径api
设置自定义错误
<httpErrors errorMode="Custom" existingResponse="Replace">
<remove statusCode="404" />
<remove statusCode="500" />
<error statusCode="404" responseMode="File" path="templates\404.json" />
<error statusCode="500" responseMode="File" path="templates\500.json" />
</httpErrors>
并且,在路径\templates
中添加文件500.json
和内容
"Code": 500,
"Message": "Something went wrong, please try again later"
现在出现内部服务器错误(http 状态码 500),这是由服务器返回的
注意:检查目录的权限,并执行iisreset
。
选项 2 - 异常过滤器
创建一个自定义 API 异常过滤器属性,该属性在异常时返回一个 json。消息可以按控制器/动作/全局自定义。
public class ApiExceptionAttribute : ExceptionFilterAttribute
string _message = null;
public ApiExceptionAttribute(string exceptionMessage = null) //to add custom message
_message = exceptionMessage;
public override void OnException(HttpActionExecutedContext context)
var message = new
ExceptionType = "Custom", //or some other detail
Message = _message == null ? "Something went wrong, please try later" : _message
;
context.Response = context.Request.CreateResponse(HttpStatusCode.SeeOther, message, "application/json");
并在 API 控制器中使用它(可选地与自定义消息一起使用)
[ApiExceptionAttribute("This end point is to test error!")]
public class TestController : ApiController
public IEnumerable<string> Get()
//actual code here
throw new Exception("Back-end exception");
【讨论】:
谢谢,但我更喜欢控制器操作中生成的动态结果 @AndreyBorisko 这个自定义ApiExceptionAttribute
有帮助吗?
谢谢,我想我找到了更好的解决方案
@AndreyBorisko 太棒了!你为什么不在这里分享你的解决方案!以上是关于ASP.NET MVC5 删除 API 错误的 html 响应的主要内容,如果未能解决你的问题,请参考以下文章
验证错误时 ASP.NET MVC5 textarea 未以红色标出
ASP.NET MVC5 KnockoutJS 映射“未捕获的类型错误:无法读取未定义的属性 'fromJS'”错误
ASP.NET MVC5 OWIN Facebook 身份验证突然不起作用
Asp.net MVC5 angular4未捕获引用错误:部署到IIS后系统未在systemjs.config.js中定义