Seis años más tarde, con MVC5 (y MVC6) en la ciudad, me encontré con este mismo problema. Estoy construyendo mi sitio con MVC5, por lo que puedo suponer con seguridad que todavía no se admite de manera inmediata. Aterricé aquí en busca de solución. Bueno, finalmente encontré la manera de arreglarlo sin hackear el controlador o su fábrica, especialmente porque solo necesitaba esta característica en solo unos pocos lugares.
El enfoque: modificando ligeramente el Command Pattern (que ya estaba usando en mi código).
Para este problema, se empieza por definir la interfaz
public interface IMyActionProcessor
{
PartialViewResult Process<T>(T theModel);
}
y la aplicación correspondiente:
public sealed class MyActionProcessor : IMyActionProcessor
{
// Your IoC container. I had it explicitly mapped just like any other
// registration to cause constructor injection. Using SimpleInjector, it will be
// <code>Container.Register(typeof(IServiceProvider),() => Container);</code>
private IServiceProvider _serviceProvider;
public MyActionProcessor(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
public PartialViewResult Process<T>(T theModel)
{
var handlerType =
typeof(IMyActionHandler<>).MakeGenericType(theModel.GetType());
dynamic handler = _serviceProvider.GetService(handlerType);
return handler.Handle((dynamic)theModel);
}
}
El manejador (userd en el código anterior) se verá así:
public interface IMyActionHandler<T> where T : class
{
PartialViewResult Execute(T theModel);
}
Con lo anterior en su lugar, todo lo que tiene que hacer es proporcionar implementaciones para la h andler basado en los detalles de su clase T
. Algo como esto:
public class ModelClassHandler : IMyActionHandler<ModelClass>
{
public PartialViewResult Execute(ModelClass theModel);
{
// Do Stuff here and return a PartialViewResult instance
}
}
Con todo lo anterior en su lugar, ahora se puede simplemente hacer esto en su controlador:
var processor = YourServiceLocator.GetService<IMyActionProcessor>();
var model = new ModelClass { /* Supply parameters */ };
var partialViewResult = processor.Process(model);
sé que es un nivel adicional de indirección pero funcionó de forma excelente. En mi caso, amplié el controlador y el procesador para que puedan devolver todo lo que quiero, no solo PartialViewResult
.
Me interesaría ver una solución más simple para esto, si existe. Supongo que no es común tener este tipo de problema al usar MVC.
PD: Cualquier buen contenedor de IoC debería poder registrar genéricos abiertos escaneando a través de ensamblajes.Por lo tanto, una vez configurado correctamente, no es necesario registrar explícitamente las implementaciones para la interfaz del controlador.
Esta publicación ([link] (http://codedrum.blogspot.com/2016/07/cannot-call-action-method-on-controller.html)) proporciona una mejor comprensión de la respuesta dada aquí, especialmente en cómo la solución puede ser generalizada. –