ASP.NET Web API 控制器创建过程()

前言

在前面对管道、路由有了基础的了解过后,本篇将带大家一起学习一下在ASP.NET Web API中控制器的创建过程,这过程分为几个部分下面的内容会为大家讲解第一个部分,也是ASP.NET Web API框架跟ASP.NET MVC框架实现上存在不同的一部分。

 

ASP.NET Web API 控制器创建、激活过程

  • ASP.NET Web API 控制器创建过程()

  • ASP.NET Web API 控制器创建过程()

  • 未完待续

 

环境描述、问题的发现

在项目运用中,我们大多数会把控制器部分从主程序抽离出来放置单独的项目中,这种情况下在使用ASP.NET MVC框架的项目环境中是不会有什么问题的,因为MVC框架在创建控制器的时候会加载当前主程序引用的所有程序集并且按照执行的搜索规则(公共类型、实现IController的)搜索出控制器类型并且缓存到xml文件中。而这种方式如果在使用了默认的ASP.NET Web API框架环境下就会有一点点的问题,这里就涉及到了Web API框架的控制器创建过程中的知识。来看一下简单的示例。

(示例还是《ASP.NET Web API 开篇介绍示例》中的示例,不过做了略微的修改,符合上述的情况。)

我们还是在SelfHost环境下做示例,来看SelfHost环境下服务端配置:

示例代码1-1

   classProgram
   {
        staticvoidMain(string[] args)
        {
            HttpSelfHostConfigurationselfHostConfiguration=
                newHttpSelfHostConfiguration("http://localhost/selfhost");
            using (HttpSelfHostServerselfHostServer=newHttpSelfHostServer(selfHostConfiguration))
            {
                selfHostServer.Configuration.Routes.MapHttpRoute(
                    "DefaultApi", "api/{controller}/{id}", new { id=RouteParameter.Optional });
 
                selfHostServer.OpenAsync();
 
                Console.WriteLine("服务器端服务监听已开启");
                Console.Read();
            }
        }
    }


代码1-1就是引用《ASP.NET Web API 开篇介绍示例》中的示例,在示例SelfHost项目中定义了API控制器,在这里我们需要把它注释掉,并且创建新的类库项目命名为WebAPIController,并且引用System.Web.Http.dll程序集和Common程序集,然后再定义个API控制器,也就是把原先在SelfHost项目中的控制器移动到新建的类库项目中。

示例代码1-2

usingSystem.Web.Http;
usingCommon;
 
namespaceWebAPIController
{
   publicclassProductController : ApiController
   {
        privatestaticList<Product>products;
 
        staticProductController()
        {
            products=newList<Product>();
            products.AddRange(
                newProduct[] 
                {
                    newProduct(){ ProductID="001", ProductName="牙刷",ProductCategory="洗漱用品"},
                    newProduct(){ ProductID="002", ProductName="《.NET框架设计—大型企业级应用框架设计艺术》", ProductCategory="书籍"}
                });
        }
        publicIEnumerable<Product>Get(stringid=null)
        {
            returnfromproductinproductswhereproduct.ProductID==id||string.IsNullOrEmpty(id) selectproduct;
        }
        publicvoidDelete(stringid)
        {
            products.Remove(products.First(product=>product.ProductID==id));
        }
        publicvoidPost(Productproduct)
        {
            products.Add(product);
        }
        publicvoidPut(Productproduct)
        {
            Delete(product.ProductID);
            Post(product);
        }
   }
}


这个时候还要记得把SelfHost项目添加WebAPIController项目的引用,要保持跟MVC项目的环境一样,然后我们在运行SelfHost项目,等待监听开启过后再使用浏览器请求服务会发现如下图所示的结果。

1

wKiom1PkKBXzjhSQAAJmM9l206Y693.jpg

看到图1中的显示问题了吧,未找到匹配的控制器类型。如果是MVC项目则不会有这样的问题,那么问题出在哪呢?实现方式的差异,下面就为大家来解释一下。

 

解决问题

在上一篇中我们最后的示意图里可以清晰的看到ASP.NET Web API框架中的管道模型最后是通过HttpControllerDispatcher类型的对象来“生成”的APIController。我们现在就来看一下HttpControllerDispatcher类型的定义。

示例代码1-3

   publicclassHttpControllerDispatcher : HttpMessageHandler
   {
        //Fields
        privatereadonlyHttpConfiguration_configuration;
        privateIHttpControllerSelector_controllerSelector;
 
        //Methods
        publicHttpControllerDispatcher(HttpConfigurationconfiguration);
        privatestaticHttpResponseMessageHandleExc