无法在 Controller “Controller”上调用操作方法“System.Web.Mvc.PartialViewResult FooT”,因为操作方法是通用方法
<% Html.RenderAction("Foo", model = Model}); %>
是否有针对 ASP MVC 2 的此限制的解决方法?我真的更喜欢使用泛型。我想出的解决方法是将模型类型更改为对象。它有效,但不是首选:
public PartialViewResult Foo<T>(T model) where T : class
{
// do stuff
}
最佳答案
在默认 ActionDescriptor 中抛出的代码:
internal static string VerifyActionMethodIsCallable(MethodInfo methodInfo) {
// we can't call instance methods where the 'this' parameter is a type other than ControllerBase
if (!methodInfo.IsStatic && !typeof(ControllerBase).IsAssignableFrom(methodInfo.ReflectedType)) {
return String.Format(CultureInfo.CurrentUICulture, MvcResources.ReflectedActionDescriptor_CannotCallInstanceMethodOnNonControllerType,
methodInfo, methodInfo.ReflectedType.FullName);
}
// we can't call methods with open generic type parameters
if (methodInfo.ContainsGenericParameters) {
return String.Format(CultureInfo.CurrentUICulture, MvcResources.ReflectedActionDescriptor_CannotCallOpenGenericMethods,
methodInfo, methodInfo.ReflectedType.FullName);
}
// we can't call methods with ref/out parameters
ParameterInfo[] parameterInfos = methodInfo.GetParameters();
foreach (ParameterInfo parameterInfo in parameterInfos) {
if (parameterInfo.IsOut || parameterInfo.ParameterType.IsByRef) {
return String.Format(CultureInfo.CurrentUICulture, MvcResources.ReflectedActionDescriptor_CannotCallMethodsWithOutOrRefParameters,
methodInfo, methodInfo.ReflectedType.FullName, parameterInfo);
}
}
// we can call this method
return null;
}
因为代码正在调用“methodInfo.ContainsGenericParameters”,我认为没有办法在不创建自己的 ActionDescriptor 的情况下覆盖此行为。从查看源代码来看,这似乎很重要。
另一种选择是使您的 Controller 类通用并创建自定义的通用 Controller 工厂。我有一些创建通用 Controller 的实验代码。它的hacky,但它只是一个个人实验。
public class GenericControllerFactory : DefaultControllerFactory
{
protected override Type GetControllerType(System.Web.Routing.RequestContext requestContext, string controllerName)
{
//the generic type parameter doesn't matter here
if (controllerName.EndsWith("Co"))//assuming we don't have any other generic controllers here
return typeof(GenericController<>);
return base.GetControllerType(requestContext, controllerName);
throw new InvalidOperationException("Generic Factory wasn't able to resolve the controller type");
}
protected override IController GetControllerInstance(System.Web.Routing.RequestContext requestContext, Type controllerType)
{
//are we asking for the generic controller?
if (requestContext.RouteData.Values.ContainsKey("modelType"))
{
string typeName = requestContext.RouteData.Values["modelType"].ToString();
//magic time
return GetGenericControllerInstance(typeName, requestContext);
}
if (!typeof(IController).IsAssignableFrom(controllerType))
throw new ArgumentException(string.Format("Type requested is not a controller: {0}",controllerType.Name),"controllerType");
return base.GetControllerInstance(requestContext, controllerType);
}
/// <summary>
/// Returns the a generic IController tied to the typeName requested.
/// Since we only have a single generic controller the type is hardcoded for now
/// </summary>
/// <param name="typeName"></param>
/// <returns></returns>
private IController GetGenericControllerInstance(string typeName, RequestContext requestContext)
{
var actionName = requestContext.RouteData.Values["action"];
//try and resolve a custom view model
Type actionModelType = Type.GetType("Brainnom.Web.Models." + typeName + actionName + "ViewModel, Brainnom.Web", false, true) ??
Type.GetType("Brainnom.Web.Models." + typeName + ",Brainnom.Web", false, true);
Type controllerType = typeof(GenericController<>).MakeGenericType(actionModelType);
var controllerBase = Activator.CreateInstance(controllerType, new object[0] {}) as IController;
return controllerBase;
}
}
关于.net - 无法在 Controller 'System.Web.Mvc.PartialViewResult Foo[T](T)' 上调用操作方法 'Controller',因为操作方法是通用方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2870116/