Método de llamada de .NET MVC en un controlador diferente

¿Alguien puede decirme cómo llamar a un método en un controlador diferente desde dentro de un método de acción? No quiero redirigir Quiero llamar a un método en un controlador diferente que devuelve una cadena y usar la respuesta dentro de mi método de acción.

Suena en mis oídos que debería refactorizar su aplicación, y extraer la funcionalidad que genera el string a una nueva clase separada (o reutilizar una clase existente, si tiene una que encaje) y dejar que ambos controladores usen esa clase.

Puede usar el siguiente enfoque para invocar un método en el otro controlador:

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

Esto funcionó para mí en ASP.NET MVC5. Espero que funcione también para ti.

¿Podría simplemente crear una instancia del controlador en su método de acción y llamar al otro método que necesita?

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

Puede lograr esto a través del método de Action de HtmlHelper .

En una vista, lo harías así:

 @Html.Action("OtherAction") 

Sin embargo, no es sencillo obtener una instancia de HtmlHelper en un método de acción (por diseño). De hecho, es un truco tan horrible que me resisto a publicarlo …

 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"); 

Esto funciona en MVC 3. Es posible que necesite eliminar el StringWriter arg del constructor ViewContext para MVC 2, IIRC.

No he usado Castle Windsor IoC, pero la teoría es que deberías poder crear una clase de fábrica de Controller personalizada, y luego ordenar al framework MVC que use esta fábrica personalizada de controladores, registrándola en el archivo Global.asax.css , en el evento Application_Start:

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

[Ver Pro Asp.Net MVC 2 Framework, Steven Sanderson, Apress, páginas 64 – 66]

De esta forma, puede crear instancias de sus controladores desde cualquier lugar de su código.

La noción de NO llamar a las acciones de otro controlador desde el controlador “actual”, o desde otro código es bastante incorrecta. Los controladores son solo clases. Solo se convierten en “Controladores” cuando MVC Framework los invoca de manera especial.

Por lo tanto, lo correcto e incorrecto de esto se reduce a POR QUÉ estás haciendo esto, no SI TENDRÍAS que hacerlo o no.

Si solo estás usando un controlador como clase, entonces está bien. Si está intentando usar esto para enviar una respuesta al usuario, entonces debe usar un RedirectToAction como se sugirió anteriormente.

Hay una serie de razones para usar un controlador como clase en lugar de como un controlador. Por ejemplo, cuando prueba su controlador. Por lo tanto, es necesario tratar a sus controladores como una clase en lugar de tratarlos de manera incorrecta.

Un ejemplo de escenario sin pruebas de usar un controlador como clase:

Estoy escribiendo un mini marco que aprovecha las capacidades de creación de plantillas del framework MVC para producir el HTML para correos electrónicos HTML, algo que todas las aplicaciones web deben hacer, por una razón u otra (por ejemplo, correos electrónicos de confirmación de pedidos).

De manera muy aproximada, instancia su MailManagerController (por simplicidad, suponga que no está utilizando IoC) en la acción de su NormalController (que necesita enviar un correo electrónico) y luego:

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

Donde RenderToString es un método de extensión en ViewResultBase que representa el resultado de una Acción (que devuelve un objeto ViewResultBase) a una cadena, y Postman es una clase estática que se ocupa de enviar correos electrónicos una vez que tiene el texto.

La belleza de esta técnica es que puede usar el marco MVC para producir correos electrónicos con plantillas, porque OrderConfirmation Action tendrá una vista asociada que no es nada sino una plantilla html para su correo electrónico que va a enviar.

Parece que estás tratando de hacer algo para lo que los controladores no están diseñados. Diseñe su método requerido como método público en alguna clase e invoque desde ambas acciones del controlador.

Estaba buscando lo mismo, pero en serio, ¿por qué la necesidad de escribir respuestas tan complicadas?

Aquí hay una publicación que responderá muy simple: Usar Html.ActionLink para llamar a la acción en un controlador diferente

Básicamente solo tienes que usar esta sobrecarga del ActionLink(HtmlHelper, String, String, String, Object, Object) : ActionLink(HtmlHelper, String, String, String, Object, Object)

Entonces tendrá: ActionLink("linkText", "actionName", "controllerName", routeValues, htmlAttributes)

Si no tiene ningún valor de ruta (que son las entradas para la acción) o htmlAttributes, debe establecerlos como nulos.

Aquí hay una llamada de ejemplo: @Html.ActionLink("Add New Student", "Create", "Student", null, new { @class = "btn btn-primary" })