У меня есть проект Web API 2 с некоторыми предопределенными контроллерами, и я создаю маршруты с использованием атрибутной маршрутизации.
У меня есть другая библиотека классов с настраиваемым контроллером web API 2, и он загружается динамически после его запроса;
Но проблема в том, что атрибут маршрутизации на вышеуказанном настраиваемом контроллере вообще не рассматривается.Есть ли способ внедрить пользовательские маршруты контроллера в основной проект веб-API?
Ниже описан способ загрузки пользовательского контроллера в проект веб-API;
Использование пользовательского контроллера httpселектор, если запрошенный контроллер не найден в проекте Web API, я загружаю библиотеку классов и пытаюсь загрузить из нее запрошенный контроллер.
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
недоступно висходный проект веб-API, поэтому, когда я выдаю запрос GET
, например http://localhost:53076/Administration
, AdministrationController
должен быть загружен из CustomModules.all и должен выполняться метод Get
.Но вместо ожидаемого списка я получаю сообщение:
«Сообщение»: «Произошла ошибка.»,
«ExceptionMessage»: «Обнаружено несколько действий, которыесоответствовать запросу:
Получить по типу CustomModules.AdministrationController
GetAccess по типу CustomModules.AdministrationController
GetInfo по типу CustomModules.AdministrationController "
Это ясно указывает на то, что атрибут маршрутизации я предоставилне считается.Любое исправление для этого?