正在调用ExceptionHandler但不返回JSON

时间:2017-12-12 17:09:22

标签: c# asp.net-web-api

我的Web API有自定义ExceptionHandler

public class GlobalExceptionHandler : ExceptionHandler
{
    private class ErrorInformation
    {
        public string Message { get; set; }
        public DateTime ErrorDate { get; set; }
    }

    public override void Handle(ExceptionHandlerContext context)
    {
        context.Result = new ResponseMessageResult(context.Request.CreateResponse(HttpStatusCode.InternalServerError,
            new ErrorInformation { Message = "We apologize but an unexpected error occurred. Please try again later.", ErrorDate = DateTime.UtcNow }));
    }
}

这是控制器代码

[HttpPost]
public async Task<HttpResponseMessage> UserNameChange(UserNameChangeRequest updateUsersRequest)
{
    throw new Exception("sdfsdf");
}

我正在注册这个

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        config.Formatters.XmlFormatter.SupportedMediaTypes.Clear();

        var json = GlobalConfiguration.Configuration.Formatters.JsonFormatter;
        json.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
        json.SerializerSettings.Converters.Add(new JsonStringEncoder());



        config.Services.Replace(typeof(IExceptionHandler), new GlobalExceptionHandler());
}

如果我放了一个断点,那就很好了。但是客户端的输出仍然是HTML,而不是预期的JSON。

更新: 我添加了以下作为过滤器属性,仍然是相同的结果。 NO JSON只是HTML错误页面          公共类CustomExceptionFilterAttribute:ExceptionFilterAttribute     {         public override void OnException(HttpActionExecutedContext actionExecutedContext)         {

        var exceptionMessage = actionExecutedContext.Exception.InnerException?.Message ?? actionExecutedContext.Exception.Message;


        var response = actionExecutedContext.Request.CreateResponse(HttpStatusCode.InternalServerError, new { Message = exceptionMessage });

        actionExecutedContext.Response = actionExecutedContext.Request.CreateResponse(HttpStatusCode.OK, new {ErrorMessage = actionExecutedContext.Exception.Message},
            new JsonMediaTypeFormatter());


    }
}

我创建了一个新项目,添加了我的NewtonSoft JSON配置和客户ErrorAtribute,按预期工作。

我的项目中有什么可以阻止错误作为JSON出现?即使我在浏览器中导航到API端点它显示为一般HTML错误,但在示例项目中使用相同的代码显示为我想要的JSON消息???

7 个答案:

答案 0 :(得分:0)

您是否尝试将MediaTypeFormatter设置为Json;

    context.Result = new ResponseMessageResult(context.Request.CreateResponse(HttpStatusCode.InternalServerError,
                new ErrorInformation { Message = "We apologize but an unexpected error occurred. Please try again later.", ErrorDate = DateTime.UtcNow }, 
                JsonMediaTypeFormatter.DefaultMediaType));

答案 1 :(得分:0)

以下是我的软件包安装

<packages>
  <package id="Microsoft.AspNet.Cors" version="5.2.3" targetFramework="net462" />
  <package id="Microsoft.AspNet.WebApi" version="5.2.2" targetFramework="net462" />
  <package id="Microsoft.AspNet.WebApi.Client" version="5.2.3" targetFramework="net462" />
  <package id="Microsoft.AspNet.WebApi.Core" version="5.2.3" targetFramework="net462" />
  <package id="Microsoft.AspNet.WebApi.Cors" version="5.2.3" targetFramework="net462" />
  <package id="Microsoft.AspNet.WebApi.WebHost" version="5.2.2" targetFramework="net462" />
  <package id="Newtonsoft.Json" version="6.0.4" targetFramework="net462" />
</packages>

它为我工作,即返回我的json数据以预防您可以删除xmlformatter,如下所示

public static void Register(HttpConfiguration config)
{
    config.Services.Replace(typeof(IExceptionHandler), new GlobalExceptionHandler());
    config.Formatters.Remove(config.Formatters.XmlFormatter);
}

下面是句柄方法

public override void Handle(ExceptionHandlerContext context)
{
   string errorMessage = "An unexpected error occured";
     var response = context.Request.CreateResponse(HttpStatusCode.InternalServerError,
                    new ErrorInformation() 
                    {
                        Message = "We apologize but an unexpected error occured. Please try again later.",
                        ErrorDate = DateTime.UtcNow 
                    }
                  );
   response.Headers.Add("X-Error", errorMessage);
   context.Result = new ResponseMessageResult(response); 
}

输出

enter image description here

答案 2 :(得分:0)

我认为你错过了以下几行:

json.UseDataContractJsonSerializer = true;

添加该行后,应该为您正确序列化为JSON。如果没有序列化程序,您可以设置格式化程序,但实际上并没有做任何事情。

根据代码,您看起来没有使用默认的Newtonsoft.Json设置,而是适用于数据合同序列化程序。

注意:只有在您不想将Newtonsoft.Json用作默认序列化程序时,此答案才有用。

答案 3 :(得分:0)

使用ExceptionLogger代替,例如:

namespace Microsoft.UPP.Calc.WebApi.Logging
{
    public sealed class AiExceptionLogger : ExceptionLogger
    {
        private readonly ITelemetryClient _telemetryClient;

        public AiExceptionLogger(ITelemetryClient telemetryClient)
        {
            _telemetryClient = telemetryClient;
        }

        public override void Log(ExceptionLoggerContext context)
        {
            LogException(context.Exception);
        }

        public void LogException(Exception exception)
        {
            var properties = Enumerable.Zip(exception.Data.Keys.Cast<string>(),
                                            exception.Data.Values.OfType<string>(),
                                            (k, v) => new { Key = k, Value = v })
                                       .Where(x => x.Value != null)
                                       .ToDictionary(x => x.Key, x => x.Value);
            _telemetryClient.TrackException(exception, properties);
        }

        public void LogEvent(string eventName, IDictionary<string, string> properties)
        {
            _telemetryClient.TrackEvent(eventName, properties);
        }
    }
}

答案 4 :(得分:0)

这是一篇很好的文章,概述了实现这一目标的一种方法。我过去使用过这种技术而且效果很好。搜索TextPlainErrorResult

Global Error Handling in ASP.NET Web API 2

要确定您的应用是否使用自定义http错误,请在IIS中的应用下打开自定义错误部分,或在web.config中查找httpErrors部分。这个结构已经存在了一段时间。如果您携带第四个遗留应用程序,请在web.config中查找以下部分:

<httpErrors errorMode="Custom" existingResponse="Auto" defaultResponseMode="ExecuteURL">
  <clear />
  <error statusCode="404" path="/errors/404.aspx" responseMode="ExecuteURL" />
  <error statusCode="500" path="/errors/500.aspx" responseMode="ExecuteURL" />
  <error statusCode="400" path="/errors/400.aspx" responseMode="ExecuteURL" />
</httpErrors>

答案 5 :(得分:0)

所以,事实证明,罪魁祸首是一个名为&#34; SerilogWeb.Classic.WebApi&#34;

的NuGet包

我不确定这个所谓的&#34;包&#34;正在做,但似乎正在拦截我的ExceptionFilters for WebApi's。

花了一整天的时间来解决这个问题,所以,我希望这可以帮助下一个有这样问题的人。

答案 6 :(得分:0)

在应用程序池中将IIS设置为使用集成模式 App pool screen shot