簡體   English   中英

如何合並WebAPI控制器中的所有“設置代碼”?

[英]How can I consolidate all of my “setup code” away from my WebAPI controllers?

我所有的控制器如下所示:

    [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對每個控制器執行所有其他操作...但是我不知道這是否可行。 我該如何實現?

您可以使用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)創建一個驗證過濾器,以便您的操作方法僅在模型狀態有效時才執行。 這樣就不再需要在操作方法中檢查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 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);
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM