前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >.Net WebApi 初探

.Net WebApi 初探

作者头像
sam dragon
发布2018-01-17 11:08:58
8770
发布2018-01-17 11:08:58
举报
文章被收录于专栏:cnblogscnblogscnblogs

实现服务层与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);
    }
}
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());
}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017-03-26 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档