C# 如何整合我所有的;设置代码";远离我的WebAPI控制器?
我所有的控制器都是这样的:C# 如何整合我所有的;设置代码";远离我的WebAPI控制器?,c#,asp.net-mvc,asp.net-web-api,C#,Asp.net Mvc,Asp.net Web Api,我所有的控制器都是这样的: [HttpPut] [Route("api/businessname")] [Authorize] public HttpResponseMessage UpdateBusinessName(BusinessNameDto model) { if (!ModelState.IsValid) return Request.CreateErrorResponse(HttpStatusCode.BadR
[HttpPut]
[Route("api/businessname")]
[Authorize]
public HttpResponseMessage UpdateBusinessName(BusinessNameDto model) {
if (!ModelState.IsValid)
return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState);
try {
_userService.UpdateBusinessName(User.Identity.Name, model.BusinessName);
return Request.CreateResponse(HttpStatusCode.OK, new ApiResponseDto() {});
} catch (Exception e) {
// logging code
//return Request.CreateResponse(HttpStatusCode.InternalServerError, e);
return Request.CreateResponse(HttpStatusCode.OK, new ApiResponseDto() { Success = false, Error = "Something bad happened :(" });
}
}
我的控制器里有很多重复的东西。理想情况下,我可以只吃这个:
[HttpPut]
[Route("api/businessname")]
[Authorize]
public HttpResponseMessage UpdateBusinessName(BusinessNameDto model) {
_userService.UpdateBusinessName(User.Identity.Name, model.BusinessName);
return Request.CreateResponse(HttpStatusCode.OK, new ApiResponseDto() {});
}
并告诉WebAPI对每个控制器执行所有其他操作。。。但我不知道这是否可能。我怎样才能做到这一点呢?您可以使用。例如,要验证请求,可以创建类似以下内容的类:
public class ValidateRequestAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(HttpActionContext actionContext)
{
if (!actionContext.ModelState.IsValid)
{
actionContext.Response = actionContext.Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState)
}
}
}
然后,您可以通过使用以下属性对Web API操作进行修饰,有选择地将筛选器应用于这些操作:
[ValidateRequest]
[HttpPut]
[Route("api/businessname")]
[Authorize]
public HttpResponseMessage UpdateBusinessName(BusinessNameDto model) {
...
}
或者使用HttpConfiguration.Filters将它们应用于Web API设置期间的所有操作:
config.Filters.Add(new ValidateRequestAttribute());
您可以执行以下操作:
1) 创建一个验证筛选器,以便仅当模型状态有效时才执行操作方法。这样您就不需要在操作方法中再检查ModelState.IsValid了
public class ValidationActionFilter : ActionFilterAttribute
{
public override void OnActionExecuting(HttpActionContext actionContext)
{
ModelStateDictionary modelState = actionContext.ModelState;
if (!modelState.IsValid)
{
actionContext.Response = actionContext.Request.CreateErrorResponse(
HttpStatusCode.BadRequest, modelState);
}
}
}
2) 创建一个异常处理筛选器,该筛选器将捕获操作方法引发的任何异常,将其序列化,并向客户端创建HTTP BADDRequest响应消息。这样你就不必再在动作方法中使用try-catch了
public class HandleExceptionFilter : ExceptionFilterAttribute
{
public override void OnException(HttpActionExecutedContext context)
{
var responseMessage = new HttpResponseMessage(HttpStatusCode.BadRequest);
responseMessage.Content = new StringContent(context.Exception.Message);
context.Response = responseMessage;
}
}
您可以通过添加以下行在WebApiConfig.cs中注册这些过滤器
config.Filters.Add(new ValidationActionFilter());
config.Filters.Add(new HandleExceptionFilter());
更新:为了更具体地描述SB2055的场景,我添加了以下代码
public class HandleExceptionFilter : ExceptionFilterAttribute
{
public override void OnException(HttpActionExecutedContext context)
{
var model = new ApiResponseDto() { Success = false, Error = context.Exception.Message })
context.Response = context.Request.CreateResponse(HttpStatusCode.OK,
model);
}
}
酷。如何将每个请求包装在try/catch中?覆盖筛选器中的OnActionExecuted
方法,并检查HttpActionExecutedContext.Exception
属性以确定是否引发了异常。然后可以相应地设置响应。另一个答案显示OnActionExecuting,而不是Executed。。。您介意提供一个示例吗?如果我想用Http.OK而不是Http.BadRequest发送自定义类型,就像我在当前代码中一样,该怎么办?在语法方面,如何发送自定义类型?我的原始语法不起作用。您在筛选器中创建了新的ApiResponseDto(){Success=false,Error=context.Exception.Message}。将其序列化为json并将其发送回。如果我可以只包含我的对象,我就必须自己序列化它,这似乎很疯狂。在接受之前,我想等着看是否有更好的方法,谢谢你