MVC 5控制器和Web Api控制器之间的抽象公共代码

本文关键字:控制器 抽象 代码 Api Web MVC 之间 | 更新日期: 2024-10-19 22:15:19

我有一个应用程序,它有一个ASP.Net MVC 5前端和一个Web Api 2服务层,我想使用依赖注入,所以MVC 5控制器只依赖于Web Api 2中的抽象。

由于Web Api控制器大多使用这种签名:

public IHttpActionResult SomeMethod(){ return Ok(); }

我的第一个想法是接口应该是:

IHttpActionResult SomeMethod();

现在我有了一个带有服务接口的类库,但这意味着这个类库需要引用System.Web.Http才能在签名中使用IHttpActionResult接口。

我有两个问题:

  1. 首先,这个库引用了System.Web.Http,这感觉是对的,有其他选择吗
  2. 如果没有其他选择,当我尝试添加引用时,我只得到一个没有该接口定义的库的旧版本,我从哪里可以得到正确的版本

谢谢。

MVC 5控制器和Web Api控制器之间的抽象公共代码

我会把公共逻辑推到一个具有"正常"输入和输出的公共库中。两个传输(MVC和webapi)可以调用这个库

这实际上取决于你想要实现什么,也就是你想要引入多少抽象。

如果您不想将所有常见的业务逻辑从这里移动到服务中进行重用,并且可能在任何地方进行重用,那么是的,您希望去掉System.Web.Http引用。

要做到这一点,需要一个干净的接口/实现,只需返回操作的结果,比如:

public interface ICustomerService 
{
    BaseResponse DoSomething(BaseRequest request);
}
public abstract class BaseResponse 
{
    public bool IsSuccess { get; set; }
    public IList<string> Errors { get; set; }
}
/*
Note: BaseResponse & BaseRequest, follow the command pattern for passing information you would impliment concrete versions of these.
*/

然后,我允许用于Web&Api控制如何使用此BaseResponse来er…response。

所以也许可以创建一个BaseControllerBaseApiController:

例如:

public abstract class BaseApiController : ApiController 
{
        protected HttpResponseMessage HandleResponse(BaseResponse response)
        {
            return
                !response.IsSuccess
                    ? Request.CreateErrorResponse(HttpStatusCode.BadRequest, response.Errors )
                    : Request.CreateResponse(HttpStatusCode.OK, response);
        }
}

和:

public abstract class BaseController : Controller
{
    protected ActionResult HandleResponse(BaseResponse response, string redirectToAction)
    {
        if (response.IsSuccess) 
            return RedirectToAction(redirectToAction);
        foreach (var error in response.Errors)
        {
            ModelState.AddModelError(string.Empty, error);
        }
        return View();
    }
}

然后在WebApi控制器:

public HttpResponseMessage DoAction(string param1)
    {
        return HandleResponse(_customerService.DoSomething(new DoActionRequest { Param1 = param1 }));
    }

在Web控制器中

public ActionResult DoAction(ViewModel viewModel)
    {
        var response = _customerService.DoSomething(new DoActionRequest { Param1 = param1 });
        return HandleResponse(response, "Success");
    }

通过这种方式,所有繁忙的逻辑都被隐藏起来并可恢复,ApiController和Controllers可以以自己独特的方式做出响应。