返回的Web API的自定义错误对象 [英] Return custom error objects in Web API
问题描述
我有一个Web API,我正在使用MVC 4个Web API框架。如果有一个例外,我目前抛出一个新的Htt presposneException。即:
如果(!Int32.TryParse(ID,出用户id))
抛出新的Htt presponseException(Request.CreateErrorResponse(的HTTPStatus code.BadRequest,无效的ID));
这返回一个对象给客户端根本就是 {消息:无效的ID}
我想通过返回一个更详细的对象,在这个反应获得更多的控制异常。像
{
状态: - 1,
子状态:3,
消息:无法找到用户
}
我将如何去这样做呢?是序列化我的错误对象,并设置它在响应消息的最佳方式?
我也进去看了 ModelStateDictionary
A位和想出了这个有点黑客,但它仍然不是一个干净的输出:
VAR MSD =新ModelStateDictionary();
msd.AddModelError(身份, - 1);
msd.AddModelError(子状态,3);
msd.AddModelError(信息,无效的东西);
抛出新的Htt presponseException(Request.CreateErrorResponse(的HTTPStatus code.BadRequest,MSD));
修改结果
看起来像一个自定义的 HTTPError这样
正是我需要的。这似乎这样的伎俩,现在让它从我的业务层...
VAR误差=新HTTPError这样的(无效的东西){{地位,-1},{子状态,3}};
抛出新的Htt presponseException(Request.CreateErrorResponse(的HTTPStatus code.BadRequest,错误));
我认为这将这样的伎俩:
业务层创建一个自定义异常类:
公共类MyException:异常
{
公共ResponseStatus状态{搞定;私人集; }
公共ResponseSubStatus子状态{搞定;私人集; }
公开新字符串消息{搞定;私人集; } 公共MyException()
{} 公共MyException(ResponseStatus状态,ResponseSubStatus子状态,字符串消息)
{
状态=地位;
子状态=子状态;
消息=消息;
}
}
创建一个静态方法来从 MyException
的情况下产生 HTTPError这样
。我使用的是反射在这里,所以我可以添加属性 MyException
,总是让他们返回W / O更新创建
:
公共静态HTTPError这样的创建和LT; T>(MyException除外),其中T:异常
{
VAR性能= exception.GetType()的GetProperties(BindingFlags.Instance
| BindingFlags.Public
| BindingFlags.DeclaredOnly);
VAR误差=新HTTPError这样的();
的foreach(在性能VAR的PropertyInfo)
{
error.Add(propertyInfo.Name,propertyInfo.GetValue(例外,NULL));
}
返回错误;
}
我现在有一个一般的异常处理程序自定义属性。类型的所有异常 MyException
将在这里处理:
公共类ExceptionHandlingAttribute:ExceptionFilterAttribute
{
公共覆盖无效onException的(HttpActionExecutedContext上下文)
{
VAR状态code =的HTTPStatus code.InternalServerError; 如果(context.Exception是MyException)
{
状态code =的HTTPStatus code.BadRequest;
抛出新的Htt presponseException(context.Request.CreateErrorResponse(状态code,HttpErrorHelper.Create(context.Exception)));
} 如果(context.Exception是的AuthenticationException)
状态code =的HTTPStatus code.Forbidden; 抛出新的Htt presponseException(context.Request.CreateErrorResponse(状态code,context.Exception.Message));
}
}
我将这个,因为我觉得在这个计划中孔玩弄了一点,更新。
I have a web api I'm working on using the MVC 4 Web API framework. If there is an exception, I'm currently throwing a new HttpResposneException. ie:
if (!Int32.TryParse(id, out userId))
throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.BadRequest, "Invalid id"));
This returns an object to the client that is simply {"message":"Invalid id"}
I would like to gain further control over this response to exceptions by returning a more detailed object. something like
{
"status":-1,
"substatus":3,
"message":"Could not find user"
}
How would I go about doing this? Is the best way to serialize my error object and set it in the response message?
I've also looked into the ModelStateDictionary
a bit and have come up with this bit of a "hack", but it's still not a clean output:
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));
edit
looks like a custom HttpError
is what I need. This seems to do the trick, now to make it extensible from my business layer...
var error = new HttpError("invalid stuff") {{"status", -1}, {"substatus", 3}};
throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.BadRequest, error));
I think this will do the trick:
Create a custom exception class for the business layer:
public class MyException: Exception
{
public ResponseStatus Status { get; private set; }
public ResponseSubStatus SubStatus { get; private set; }
public new string Message { get; private set; }
public MyException()
{}
public MyException(ResponseStatus status, ResponseSubStatus subStatus, string message)
{
Status = status;
SubStatus = subStatus;
Message = message;
}
}
Create a static method to generate a HttpError
from an instance of MyException
. I'm using reflection here so I can add properties to MyException
and always have them returned w/o updating Create
:
public static HttpError Create<T>(MyException exception) where T:Exception
{
var properties = exception.GetType().GetProperties(BindingFlags.Instance
| BindingFlags.Public
| BindingFlags.DeclaredOnly);
var error = new HttpError();
foreach (var propertyInfo in properties)
{
error.Add(propertyInfo.Name, propertyInfo.GetValue(exception, null));
}
return error;
}
I currently have a custom attribute for a general exception handler. All exceptions of type MyException
will be handled here:
public class ExceptionHandlingAttribute : ExceptionFilterAttribute
{
public override void OnException(HttpActionExecutedContext context)
{
var statusCode = HttpStatusCode.InternalServerError;
if (context.Exception is MyException)
{
statusCode = HttpStatusCode.BadRequest;
throw new HttpResponseException(context.Request.CreateErrorResponse(statusCode, HttpErrorHelper.Create(context.Exception)));
}
if (context.Exception is AuthenticationException)
statusCode = HttpStatusCode.Forbidden;
throw new HttpResponseException(context.Request.CreateErrorResponse(statusCode, context.Exception.Message));
}
}
I'll play around with this a bit more and update as I find holes in this plan.
这篇关于返回的Web API的自定义错误对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!