asp.net-mvc-4 - 在Web API中返回自定义错误对象

标签 asp.net-mvc-4 exception-handling error-handling asp.net-web-api

我有一个正在使用MVC 4 Web API框架的Web API。如果有异常,我当前抛出一个新的HttpResponseException。即:

if (!Int32.TryParse(id, out userId))
    throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.BadRequest, "Invalid id")); 

这会向客户端返回一个简单的对象{"message":"Invalid id"}
我想通过返回更详细的对象来进一步控制对此异常的响应。就像是
{
 "status":-1,
 "substatus":3,
 "message":"Could not find user"
 }

我将如何去做呢?是序列化错误对象并将其设置在响应消息中的最佳方法吗?

我也仔细研究了ModelStateDictionary并提出了这种“hack”,但它仍然不是一个干净的输出:
var msd = new ModelStateDictionary();
msd.AddModelError("status", "-1");
msd.AddModelError("substatus", "3");
msd.AddModelError("message", "invalid stuff");
throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.BadRequest, msd));

编辑
看起来像我需要的自定义HttpError。这似乎可以解决问题,现在可以从我的业务层进行扩展...
var error = new HttpError("invalid stuff") {{"status", -1}, {"substatus", 3}};
throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.BadRequest, error));

最佳答案

这些答案比他们需要的复杂得多。

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        config.Filters.Add(new HandleApiExceptionAttribute());
        // ...
    }
}

public class HandleApiExceptionAttribute : ExceptionFilterAttribute
{
    public override void OnException(HttpActionExecutedContext context)
    {
        var request = context.ActionContext.Request;

        var response = new
        {
             //Properties go here...
        };

        context.Response = request.CreateResponse(HttpStatusCode.BadRequest, response);
    }
}

这就是您所需要的。单元测试也很好,也很容易:
[Test]
public async void OnException_ShouldBuildProperErrorResponse()
{
    var expected = new 
    {
         //Properties go here...
    };

    //Setup
    var target = new HandleApiExceptionAttribute()

    var contextMock = BuildContextMock();

    //Act
    target.OnException(contextMock);

    dynamic actual = await contextMock.Response.Content.ReadAsAsync<ExpandoObject>();

    Assert.AreEqual(expected.Aproperty, actual.Aproperty);
}

private HttpActionExecutedContext BuildContextMock()
{
    var requestMock = new HttpRequestMessage();
    requestMock.Properties.Add(HttpPropertyKeys.HttpConfigurationKey, new HttpConfiguration());

    return new HttpActionExecutedContext()
    {
        ActionContext = new HttpActionContext
        {
            ControllerContext = new HttpControllerContext
            {
                Request = requestMock
            }

        },
        Exception = new Exception()
    };
}

关于asp.net-mvc-4 - 在Web API中返回自定义错误对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16243021/

相关文章:

asp.net - 如果 session 超时, "HttpContext.Current.User.Identity.Name"是否返回 null?

asp.net-mvc-3 - Bootstrap 下拉菜单在 MVC 4 中共享的 _Layout.cshtml 中不起作用

python - 有没有办法在不进行硬编码的情况下编写相同的 try- except 多行代码? Python

c - 无效参数读写文件

javascript - 在 MVC 4 上使用 FineUploader 手动触发上传

asp.net - 使用 AngularJS 和 Asp.Net MVC 上传带有 FormData 的多个文件

c# - 是否可以在某些场景中吞下除关键异常之外的所有异常?

c++ - 如何从 CloseHandle() 捕获异常

Python:通过具有多个 Excepts 的 Try/Except block 传播异常

php - 不要中止对ErrorException的响应