Метод MVC MVC для разных контроллеров

Может ли кто-нибудь сказать мне, как вызвать метод на другом контроллере из метода действия? Я не хочу перенаправлять. Я хочу вызвать метод на другом контроллере, который возвращает строку и использовать ответ в моем методе действий.

Ответ 1

Звучит в моих ушах, как вы должны реорганизовывать свое приложение, и извлекать функциональные возможности, которые генерируют строку для нового отдельного класса (или повторно использовать существующий класс, если у вас есть тот, который подходит), и пусть оба контроллера используют этот класс.

Ответ 2

Вы можете использовать следующий подход для вызова метода на другом контроллере:

var otherController = DependencyResolver.Current.GetService<OtherController>();
var result = otherController.SomeMethod();

Это работало для меня в ASP.NET MVC5. Надеюсь, что это сработает и для вас.

Ответ 3

Не могли бы вы просто создать экземпляр контроллера в своем методе действий и вызвать другой метод, который вам нужен?

public ActionResult YourActionMethod()
{
   SomeController c = new SomeController();
   ActionResult result = c.SomeMethod();

   return View();
}

Ответ 4

Это можно сделать с помощью Action метода HtmlHelper.

В представлении вы сделаете это следующим образом:

@Html.Action("OtherAction")

Однако не просто получить экземпляр HtmlHelper в методе действий (по дизайну). На самом деле это такой ужасный хак, что я не хочу даже публиковать его...

var htmlHelper = new HtmlHelper(new ViewContext(
                                      ControllerContext, 
                                      new WebFormView(ControllerContext, "HACK"),
                                      new ViewDataDictionary(),
                                      new TempDataDictionary(),
                                      new StringWriter()),
                                new ViewPage());

var otherViewHtml = htmlHelper.Action("ActionName", "ControllerName");

Это работает на MVC 3. Вам может потребоваться удалить arg StringWriter из конструктора ViewContext для MVC 2, IIRC.

</обходное >

Ответ 5

Я не использовал Castle Windsor IoC, но теория заключается в том, что вы должны иметь возможность создать собственный класс контроллера factory, а затем проинструктировать структуру MVC для использования этого настраиваемого контроллера factory, зарегистрировав его в файл Global.asax.css в событии Application_Start:

protected void Application_Start()
{
   RegisterRoutes(RouteTable.Routes);
   ControllerBuilder.Current.SetControllerFactory(new MyCustomControllerFactor());
}

[См. Pro Asp.Net MVC 2 Framework, Стивен Сандерсон, Apress, страницы 64 - 66]

Таким образом, вы можете создавать экземпляры своих контроллеров из любого места вашего кода.

Понятие НЕ вызывать действия другого контроллера из "текущего" контроллера или из другого кода является совершенно неправильным. Контроллеры - это просто классы. Они становятся только "контроллерами" при специальном вызове MVC Framework.

Следовательно, правильное и неправильное это сводится к ПОЧЕМУ вы делаете это, а не ТО, ЧТО вы должны или нет.

Если вы просто используете контроллер как класс, то это нормально. Если вы пытаетесь использовать это для отправки ответа пользователю, вам следует использовать RedirectToAction, как было предложено выше.

Существует несколько причин использовать контроллер как класс, а не как контроллер. Например, при тестировании вашего контроллера. Поэтому обращение с вашими контроллерами из класса необходимо в противоположность неправильному.

Пример сценария без тестирования использования контроллера как класса:

Я пишу мини-фреймворк, который использует возможности моделирования шаблонов MVC для создания электронных писем HTML для HTML, что необходимо всем веб-приложениям по той или иной причине (например, письма с подтверждением заказа).

Очень грубо, вы создаете экземпляр своего MailManagerController (для простоты, предположим, что вы не используете IoC) в вашем действии NormalController (которому нужно отправить электронное письмо), а затем выполните:

MailManagerController mailmanager = new MailManagerController();
string html = mailmanager.OrderConfirmation(order).RenderToString();
Postman.SendEmail(html, order.UserEmailAddress, "MyApp order confirmation");

Где RenderToString - это метод расширения в ViewResultBase, который отображает вывод Action (который возвращает объект ViewResultBase) в строку, а Postman - это статический класс, который обрабатывает отправку писем после того, как вы получили текст.

Красота этой техники заключается в том, что вы можете использовать структуру MVC для создания шаблонных писем, потому что в действии OrderConfirmation Action есть связанное представление, которое не является ничем, если не является шаблоном html для вашего электронного письма, которое вы собираетесь отправить.

Ответ 6

Похоже, вы пытаетесь сделать что-то, для чего не предназначены контроллеры. Создайте свой необходимый метод как открытый метод в каком-то классе и вызовите из обоих действий контроллера.

Ответ 7

Я искал то же самое, но серьезно люди, почему нужно писать такие сложные ответы.

Здесь сообщение, которое ответит на него очень просто: Использование Html.ActionLink для вызова действия на другом контроллере

В основном вам просто нужно использовать эту перегрузку actionlink: ActionLink(HtmlHelper, String, String, String, Object, Object)

Итак, у вас будет: ActionLink("linkText", "actionName", "controllerName", routeValues, htmlAttributes)

Если у вас нет параметров routeValues ​​(которые являются вводом для действия) или htmlAttributes, вы должны установить их как null.

Вот пример: @Html.ActionLink("Add New Student", "Create", "Student", null, new { @class = "btn btn-primary" })