如何从我的Web API控制器中整合出所有“设置代码”?

时间:2014-10-08 20:13:36

标签: 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.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为每个控制器做所有其他事情......但我不知道这是否可能。我怎样才能做到这一点?

2 个答案:

答案 0 :(得分:1)

您可以使用ActionFilterAttributes。例如,要验证请求,您可以创建类似于此的类:

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 :(得分:1)

您可以执行以下操作:

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)创建一个异常处理过滤器,它将捕获action方法抛出的任何异常,将其序列化并向客户端创建HTTP BadRequest响应消息。这样你就不必再在动作方法中使用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);
    }
}