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 中删除了问题中提到的设置,并在此处添加了空的 &lt;customErrors mode="On"&gt;&lt;/customErrors&gt;

    添加类似于 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 自定义身份验证

验证错误时 ASP.NET MVC5 textarea 未以红色标出

ASP.NET MVC5 KnockoutJS 映射“未捕获的类型错误:无法读取未定义的属性 'fromJS'”错误

Asp.net 身份用户,添加名字和姓氏

ASP.NET MVC5 OWIN Facebook 身份验证突然不起作用

Asp.net MVC5 angular4未捕获引用错误:部署到IIS后系统未在systemjs.config.js中定义