zoukankan      html  css  js  c++  java
  • .Net WebApi 初探

    实现服务层与api层共用,也就表明Service层就是api层。

    • 关键类和接口

      • System.Web.Http.Dispatcher.DefaultHttpControllerSelector

      webpai选择控制器的默认实现,可以重写SelectController方法

      • System.Web.Http.Controllers.ApiControllerActionSelector

      webapi选择指定控制器下的action的默认实现,可以重写SelectAction方法。

      • System.Web.Http.ApiController

      api控制器的基类,继承于此的类都可以成为Api控制器

    • 类和接口关系图 api自定义扩展实现

    api注册流程

    如果实现Servie层的Controller。

    • 所有服务类都需要继承于ApiController类,让服务类拥有控制器的特性 ApiServier类代码(继承ApiController此可,设置服务基类用于后期扩展):
    public class ApiService:System.Web.Http.ApiController
    {
    }

    TestServer类代码:

    public class TestService:ApiService
    {
        public string Get()
        {
            return "Get-Test";
        }
    }

    实现服务类,且具有ApiController的能力

      • 实现ServiceContainer类,实现服务类的缓存,并用于Controller的选择类,获取服务类代码如下:
    private void Init()
    {
        var assembly = System.Reflection.Assembly.GetExecutingAssembly();
        var ls = assembly.GetTypes().Where(x => typeof(Services.ApiService).IsAssignableFrom(x));
        foreach(var item in ls)
        {
            _apis.Add(item.FullName, item);
        }
    }
      • 重写api选择controller类代码:
    public class CustomSelectController:System.Web.Http.Dispatcher.DefaultHttpControllerSelector
    {
        public CustomSelectController(System.Web.Http.HttpConfiguration config) : base(config)
        {
    
        }
    
        public override HttpControllerDescriptor SelectController(HttpRequestMessage request)
        {
            var routeData = request.GetRouteData().Values;
            foreach( var route in routeData)
            {
                if(route.Key == "controller")
                {
                    //找controller
                    var controllerType = ServicesContainer.CreateInstance().Apis
                        .Where(x => x.Key.ToLower().IndexOf(route.Value.ToString() + "service") > 0).FirstOrDefault();
                    if (controllerType.Value!=null)
                    {
                        return new DyControllerDescriptor(request.GetConfiguration(), controllerType.Value);
                    }
                }
            }
    
            return base.SelectController(request);
        }
    }

    注意:

    1. 选择Controller类必须有一个参数的构造函数,构造函数传入为httpConfiguration类
    2. 重写SelectController方法,实现从ServiceContainer中获取ApiService实现类
    3. 重写ActionSelector类
    public class CustomActionActivator:System.Web.Http.Controllers.ApiControllerActionSelector
    {
        public override HttpActionDescriptor SelectAction(HttpControllerContext controllerContext)
        {
            if (!(controllerContext.ControllerDescriptor is DyControllerDescriptor))
            {
                return base.SelectAction(controllerContext);
            }
    
            var realType = controllerContext.ControllerDescriptor as DyControllerDescriptor;
    
    
            Type[] types = new Type[0];
            System.Reflection.MethodInfo methodInfo = realType.ControllerInfo.GetMethod("Get", 
                types);
    
            return new DyActionDescriptor(controllerContext.Configuration, controllerContext.ControllerDescriptor, methodInfo);
        }
    }
    • 注意:

      1. 此类不重写也可以实现ApiService类的执行,此类主要是处理在Action执行前一个些额外操作。
      2. 从中我们也可以看出Action的执行也是需要MethodInfo这个类的实例。
    • Global.cs中注入Api路由时,必须在Mvc注入路由之前

    protected void Application_Start()
    {
        common.ServicesContainer.CreateInstance();
    
        AreaRegistration.RegisterAllAreas();
    
        //必须放在RouteConfig.RegisterRoutes前面
        GlobalConfiguration.Configure((config) =>
        {
            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );
        });
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        BundleConfig.RegisterBundles(BundleTable.Bundles);
    
        GlobalConfiguration.Configuration.Services.Replace(typeof(System.Web.Http.Dispatcher.IHttpControllerSelector),
            new common.CustomSelectController(GlobalConfiguration.Configuration));
        GlobalConfiguration.Configuration.Services.Replace(typeof(System.Web.Http.Controllers.IHttpActionSelector), new common.CustomActionActivator());
    }

    运行结果:

  • 相关阅读:
    1069.查找学生信息
    1023.Excel排序
    1061.成绩排序
    bzoj 1113
    bzoj 1112 treap树
    bzoj 1225 dfs + 一点点数论
    bzoj 1224
    UESTC
    HDU 3530 单调队列
    bzoj 1233
  • 原文地址:https://www.cnblogs.com/cqhaibin/p/6624189.html
Copyright © 2011-2022 走看看