我有一个带有一些预定义控制器的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”
这显然表明未考虑我提供的属性路由。有解决办法吗?