解决MVC的Controller和Web API的Controller类名不能相同的问题

解决MVC的Controller和Web API的Controller类名不能相同的问题

 

问题描述:

在Area的一个项目文件夹内,在Controller中我们要创建Mvc Controller及Api Controller,假如一个购物车的业务(shopcard)
mvc路由注册为~/{controller}/{action},我希望的访问地址应该是 ~/shopcard/action
api中由注册为~/api/{controller},我希望的访问地址应该是 ~/api/shopcard
那么问题就产生了,微软设计这个框架是通过类名去匹配的 mvc下你创建一个 shopcardController继承Controller,就不能再创建一个同名的shopcardController继承ApiController,这样的话mvc的访问地址和api的访问地址必须要有一个名字不能叫shopcard,不得不改名

 

问题原因:

通过查看微软System.Web.Http的源码,我们发现其实这个问题也很好解决,在这个DefaultHttpControllerSelector类中,微软有定义Controller的后缀

我们只要把ApiController的后缀改成和MVC不一样,就可以解决问题了。这个字段是个静态只读的Field,我们只要把它改成ApiContrller就解决问题了

 

解决方法:

可以利用反射解决这个问题,在注册Api路由前添加以下代码即可完成,代码如下:

var suffix = typeof(DefaultHttpControllerSelector).GetField("ControllerSuffix", BindingFlags.Static | BindingFlags.Public);
            if (suffix != null) suffix.SetValue(null, "ApiController");

 

demo

controller:

public class shopCardController : Controller
    {
        // GET: shop/shopCard
        [System.Web.Mvc.HttpGet]
        public ActionResult Index()
        {
            return View();
        }
    }

    public class shopCardApiController:ApiController
    {
        [System.Web.Http.HttpGet]
        public string Get(string id)
        {
            return "test";
        }
    }

webApi route:

public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            // Web API 配置和服务
            var suffix = typeof(DefaultHttpControllerSelector).GetField("ControllerSuffix", BindingFlags.Static | BindingFlags.Public);
            if (suffix != null) suffix.SetValue(null, "ApiController");


            // Web API 路由
            config.MapHttpAttributeRoutes();

            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );
        }
    }

 

posted @ 2020-06-17 14:44  youguess  阅读(656)  评论(0编辑  收藏  举报