Подтвердить что ты не робот

В asp.net mvc можно создать общий контроллер?

Я пытаюсь создать общий контроллер, т.е.

public class MyController<T> : Controller where T : SomeType
{ ... }

Однако, когда я пытаюсь его использовать, я всюду сталкиваюсь с этой ошибкой...

Имя контроллера должно заканчиваться на "Контроллер"

Итак, мой вопрос: возможно ли создать общий контроллер в asp.net mvc?

Спасибо!

4b9b3361

Ответ 1

Если я правильно вас понимаю, то, что вы пытаетесь сделать, направляет все запросы для данной модели через общий контроллер типа T.

Вы хотите, чтобы T изменялся в зависимости от запрашиваемой модели.

Вы хотели бы, чтобы /Product/Index запускал MyController<Product>.Index()

Это можно сделать, написав собственный IControllerFactory и внедряя метод CreateController следующим образом:

public IController CreateController(RequestContext requestContext, string controllerName)
{
    Type controllerType = Type.GetType("MyController")
                              .MakeGenericType(Type.GetType(controllerName));
    return Activator.CreateInstance(controllerType) as IController;
}

Ответ 2

Да, вы можете, это хорошо, и я сам использовал их сами.

Что вам нужно, так это то, что когда вы наследуете MyController, вы по-прежнему заканчиваете имя типа контроллером:

public class FooController :  MyController<Foo>
{ 
 ...
}

Ответ 3

Контроллер по умолчанию factory использует "соглашение" вокруг имен контроллеров, когда пытается найти контроллер для отправки запроса. Вы могли бы переопределить эту функциональность поиска, если хотите, что позволило бы вашему универсальному контроллеру работать.

Эта статья MSDN...

http://msdn.microsoft.com/en-us/magazine/dd695917.aspx

... имеет хорошую запись о том, что происходит.

Ответ 4

Это дубликат универсального контроллера asp.net mvc, который фактически содержит правильный ответ. Ответ Джеффа Фрица абсолютно неверен. Создание собственного IControllerFactory не пройдет мимо ограничения в ExpressionHelper.GetRouteValuesFromExpression, которое генерирует ошибку, которую вы видите. Внедрение собственного IControllerFactory будет по-прежнему оставлять вас с ошибками всякий раз, когда вы вызываете RedirectToAction, BuildUrlFromExpression, ActionLink, RenderAction, BeginForm, любые любые методы, которые их называют.

Что мне интересно, так это то, что Microsoft "ограничение по соглашению" уже применяется ограничением "где TController: Controller", которое помещается на тип метода ExpressionHelper.GetRouteValuesFromExpression. Ни один из родословных никогда не будет удовлетворять проверке соглашения:

string controllerName = typeof(TController).Name;
if (!controllerName.EndsWith("Controller", StringComparison.OrdinalIgnoreCase)) {
    throw new ArgumentException(MvcResources.ExpressionHelper_TargetMustEndInController, "action");
}

если он не наследуется классом, заканчивающимся в "Контроллере", потому что typeof (AnyGeneric).Name никогда не заканчивается "Контроллером".

Ответ 5

Если бы я был вами, я бы получил источник MVC и создал тестовый MVC-проект с исходным кодом, чтобы вы могли изучить, где генерируется исключение и видят, что вы можете делать с вашей общей идеей и с соблюдением правил именования "контроллера".