C# ASP.NET MVC5删除API错误的html响应

C# ASP.NET MVC5删除API错误的html响应,c#,asp.net,asp.net-mvc,asp.net-web-api2,C#,Asp.net,Asp.net Mvc,Asp.net Web Api2,我想知道如何更好地解决这个问题 该应用程序已注册mvc web和web api。我有一个单独的mvc web控制器(称为Error),负责呈现错误页面。 我的web.config看起来像: <system.webServer> <httpErrors errorMode="Custom" existingResponse="Replace"> <remove statusCode="404" /> <remove st

我想知道如何更好地解决这个问题

该应用程序已注册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返回一些对象,并在动作中设置错误头,或者只设置没有数据的错误头,该怎么办


谢谢

我不确定这是否是您正试图精确执行的操作,但如果您只是想在出错时发送和对象(json),您可以尝试一下。这当然不是最好的出路

其思想是将静态对象保存为文件中的文本,并在出现错误时提供文件内容

web.config

<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>
现在是内部服务器错误(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(“此终点是测试错误!”)]
公共类TestController:ApicController
{
公共IEnumerable Get()
{
//这里的实际代码
抛出新异常(“后端异常”);
}
}

我找到了一个运行良好的解决方案,但我没有对Web API方面做任何更改,而是对MVC Web进行了更改

因此,在阅读之后,我意识到,Web API异常将不会在global.asax中处理,为此,您需要注册IEExceptionLogger或IEExceptionHandler。因此,我为解决问题所做的是:

  • 从web.config中删除了问题中提到的设置,并在那里添加了空的
  • 添加类似于Global.asax的内容(基于):

  • 因此,这段代码只负责Mvc网页。ErrorController决定需要渲染的视图

    WebAPI的默认行为没有改变,所以它和以前一样工作,并且不会在响应中呈现任何错误html。他们现在分开了。在我可以手动执行的操作中:

    return NotFound();
    
    我看到空的响应体,或者用这样的东西控制它

    return Request.CreateResponse(HttpStatusCode.BadRequest, error);
    

    谢谢,但我更喜欢控制器中生成的动态结果actions@AndreyBorisko这个定制的
    ApiExceptionAttribute
    有帮助吗?谢谢,我想我找到了一个更好的solution@AndreyBorisko伟大的你为什么不在这里分享你的解决方案呢!我会看一看,我必须添加Response.End();在ShowWebErrorPage方法和响应的末尾。TrySkipIisCustomErrors=true;在控制器操作方法中,以避免从IIS提交的空白页。
    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));
    }
    
    return NotFound();
    
    return Request.CreateResponse(HttpStatusCode.BadRequest, error);