映射动态加载的Web API 2控制器的属性路由

时间:2018-09-18 06:25:33

标签: c# asp.net-web-api2

我有一个带有一些预定义控制器的Web API 2项目,我正在使用属性路由创建路由。

我还有一个带有Web API 2自定义控制器的类库,并在其请求后动态加载;

但是问题是根本没有考虑上述定制控制器上的属性路由。有什么方法可以将自定义控制器路由注入到主要的Web API项目?

以下是我将自定义控制器加载到Web API项目的方式;

如果在Web API项目中找不到请求的控制器,请使用自定义的http控制器选择器。我加载了类库,并尝试从中加载请求的控制器。

CustomHttpControllerSelector.cs

public class CustomHttpControllerSelector : DefaultHttpControllerSelector
    {
        private readonly HttpConfiguration _configuration;

    public CustomHttpControllerSelector(HttpConfiguration configuration) : base(configuration)
    {
        _configuration = configuration;
    }

    public override HttpControllerDescriptor SelectController(HttpRequestMessage request)
    {
        HttpControllerDescriptor controller;
        try
        {
            //Select the requested controller
            controller = base.SelectController(request);
        }
        catch (Exception)
        {
            //Try to load the requested controller from the custom dll
            controller = GetCustomContoller(request);
        }
        return controller;
    }

    private HttpControllerDescriptor GetCustomContoller(HttpRequestMessage request)
    {
        HttpControllerDescriptor controller;

        try
        {
            string controllerName = base.GetControllerName(request);
            string controllerFormatName = string.Format("{0}Controller", controllerName);
            string applicationPath = string.Format(@"{0}\PlugIns\CustomModules.dll", HostingEnvironment.ApplicationPhysicalPath);

            Assembly assembly = Assembly.LoadFile(applicationPath);
            if (assembly == null)
                throw new HttpResponseException(request.CreateErrorResponse(HttpStatusCode.InternalServerError, "CustomModules.dll not found."));

            Type controllerType = assembly.GetTypes()
              .Where(i => typeof(IHttpController).IsAssignableFrom(i))
              .FirstOrDefault(i => i.Name.Equals(controllerFormatName, StringComparison.OrdinalIgnoreCase));

            if (controllerType == null)
                throw new HttpResponseException(request.CreateErrorResponse(HttpStatusCode.InternalServerError, string.Format("{0} not found.", controllerFormatName)));

            controller = new HttpControllerDescriptor(_configuration, controllerName, controllerType);
        }
        catch (Exception)
        {

            throw;
        }

        return controller;
    }
}

WebApiConfig.cs

public static void Register(HttpConfiguration config)
{
   // Web API configuration and services
    config
       .Services
       .Replace(typeof(IHttpControllerSelector), new CustomHttpControllerSelector(config));

   // Web API routes
   config.MapHttpAttributeRoutes();

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

自定义控制器-AdministrationController.cs

    [RoutePrefix("Administration")]
    public class AdministrationController : ApiController
    {
        [HttpGet, Route("")]
        public IEnumerable<string> Get()
        {
            return new List<string>() { "Item 01", "Item 02", "Item 03" };
        }

        [HttpGet, Route("Access")]
        public HttpResponseMessage GetAccess()
        {
            return Request.CreateResponse(HttpStatusCode.OK, "Access Granted.");
        }

        [HttpGet, Route("Info")]
        public DataTable GetInfo()
        {
            return new DataTable();
        }
    }

AdministrationController在原始Web API项目中不可用,因此当我发出GET之类的http://localhost:53076/Administration请求时,AdministrationController应该从CustomModules.all加载,并且方法Get应该被执行。但是,我收到的消息不是预期的列表,而是以下消息;

  

“消息”:“发生错误。”,
  “ ExceptionMessage”:“找到与请求匹配的多个动作:
  进入类型CustomModules.AdministrationController
  类型CustomModules.AdministrationController上的GetAccess
  类型为CustomModules.AdministrationController的GetInfo”

这显然表明未考虑我提供的属性路由。有解决办法吗?

0 个答案:

没有答案