Существует ли способ изменить соглашение о присвоении имен для контроллеров в ASP.NET MVC?
То, что я хочу, должно назвать мои контроллеры InicioControlador
вместо InicioController
, или еще лучше, используйте префикс вместо суффикса и имейте ControladorInicio
как мое название контроллера.
Из того, что я читал до сих пор, я думаю, что должен реализовать свою собственную Фабрику Контроллера. Я был бы очень благодарен, если какой-либо из Вас мог бы указать на меня в правильном направлении.
Да, ControllerFactory - лучшее решение вашей проблемы.
public IController CreateController(RequestContext requestContext, string controllerName)
{
BaseController controller;
switch (controllerName.ToLower())
{
case "product": case "products": controller = new MyProductController(); break;
case "home": controller = new MyHomeController(); break;
case "account": controller = new MyAccountController(); break;
default: controller = null; break;
}
return controller;
}
Это мой первый ControllerFactory, но он очень глупый :) Вы должны использовать отражение и избегать этого уродливого переключателя.
Я решил копнуть немного глубже и после поиска в исходном коде MVC нашел именно то, что искал. Соглашение об именах контроллеров находится глубоко внутри MVC Framework, особенно в двух классах ControllerDescriptor
и ControllerTypeCache
.
В ControllerDescriptor
он задается следующим атрибутом:
public virtual string ControllerName {
get {
string typeName = ControllerType.Name;
if (typeName.EndsWith("Controller", StringComparison.OrdinalIgnoreCase)) {
return typeName.Substring(0, typeName.Length - "Controller".Length);
}
return typeName;
}
}
В ControllerTypeCache
он задается следующими методами:
internal static bool IsControllerType(Type t) {
return
t != null &&
t.IsPublic &&
t.Name.EndsWith("Controller", StringComparison.OrdinalIgnoreCase) &&
!t.IsAbstract &&
typeof(IController).IsAssignableFrom(t);
}
public void EnsureInitialized(IBuildManager buildManager)
{
if (_cache == null)
{
lock (_lockObj)
{
if (_cache == null)
{
List<Type> controllerTypes = TypeCacheUtil.GetFilteredTypesFromAssemblies(_typeCacheName, IsControllerType, buildManager);
var groupedByName = controllerTypes.GroupBy(
t => t.Name.Substring(0, t.Name.Length - "Controller".Length),
StringComparer.OrdinalIgnoreCase);
_cache = groupedByName.ToDictionary(
g => g.Key,
g => g.ToLookup(t => t.Namespace ?? String.Empty, StringComparer.OrdinalIgnoreCase),
StringComparer.OrdinalIgnoreCase);
}
}
}