有没有办法在 MVC3 中创建一个仅包含控制器名称但不包含其参数的 URL 我做了@url.Action("action","controller",the model)
一个我希望用户看到的操作;'/controller/action' 不是 '/controller/action?....&..&..' 我不知道我该怎么做。
问问题
604 次
1 回答
1
您可以使用 MVC 控制库。我做了类似的事情而不需要 contrlib
public static class UrlExtensions
{
public static string Action<TController>(this UrlHelper urlHelper, Expression<Action<TController>> expression) where TController : Controller
{
return BuildUrlFromExpression(urlHelper.RequestContext, urlHelper.RouteCollection, expression);
}
public static string ActionWithParameters<TController>(this UrlHelper urlHelper, Expression<Action<TController>> expression) where TController : Controller
{
return BuildUrlFromExpressionWithParameters(urlHelper.RequestContext, urlHelper.RouteCollection, expression);
}
public static RedirectToRouteResult Redirect<TController>(this TController controller, Expression<Action<TController>> expression) where TController : Controller
{
var valuesFromExpression = ExpressionHelper.GetRouteValuesFromExpressionWithParameters(expression);
return new RedirectToRouteResult(valuesFromExpression);
}
private static string BuildUrlFromExpression<TController>(RequestContext context, RouteCollection routeCollection, Expression<Action<TController>> action) where TController : Controller
{
var valuesFromExpression = ExpressionHelper.GetRouteValuesFromExpression(action);
var virtualPathForArea = RouteCollectionExtensions.GetVirtualPathForArea(routeCollection, context, valuesFromExpression);
if (virtualPathForArea != null)
return virtualPathForArea.VirtualPath;
return null;
}
private static string BuildUrlFromExpressionWithParameters<TController>(RequestContext context, RouteCollection routeCollection, Expression<Action<TController>> action) where TController : Controller
{
var valuesFromExpression = ExpressionHelper.GetRouteValuesFromExpressionWithParameters(action);
var virtualPathForArea = RouteCollectionExtensions.GetVirtualPathForArea(routeCollection, context, valuesFromExpression);
if (virtualPathForArea != null)
return virtualPathForArea.VirtualPath;
return null;
}
}
public static class ExpressionHelper
{
public static RouteValueDictionary GetRouteValuesFromExpression<TController>(Expression<Action<TController>> action) where TController : Controller
{
MethodCallExpression call;
return GetRouteValuesFromExpression(action, out call);
}
public static RouteValueDictionary GetRouteValuesFromExpressionWithParameters<TController>(Expression<Action<TController>> action) where TController : Controller
{
MethodCallExpression call;
var rvd = GetRouteValuesFromExpression(action, out call);
AddParameterValuesFromExpressionToDictionary(rvd, call);
return rvd;
}
private static RouteValueDictionary GetRouteValuesFromExpression<TController>(Expression<Action<TController>> action, out MethodCallExpression call) where TController : Controller
{
if (action == null)
throw new ArgumentNullException("action");
call = action.Body as MethodCallExpression;
if (call == null)
throw new ArgumentException("MustBeMethodCall", "action");
string name = typeof(TController).Name;
if (!name.EndsWith("Controller", StringComparison.OrdinalIgnoreCase))
throw new ArgumentException("TargetMustEndInController", "action");
string str = name.Substring(0, name.Length - "Controller".Length);
if (str.Length == 0)
throw new ArgumentException("CannotRouteToController", "action");
string targetActionName = GetTargetActionName(call.Method);
var rvd = new RouteValueDictionary();
rvd.Add("Controller", (object)str);
rvd.Add("Action", (object)targetActionName);
var linkAreaAttribute = typeof(TController).GetCustomAttributes(typeof(ActionLinkAreaAttribute), true).FirstOrDefault() as ActionLinkAreaAttribute;
if (linkAreaAttribute != null)
{
string area = linkAreaAttribute.Area;
rvd.Add("Area", (object)area);
}
return rvd;
}
public static string GetInputName<TModel, TProperty>(Expression<Func<TModel, TProperty>> expression)
{
if (expression.Body.NodeType == ExpressionType.Call)
return GetInputName((MethodCallExpression)expression.Body).Substring(expression.Parameters[0].Name.Length + 1);
else
return expression.Body.ToString().Substring(expression.Parameters[0].Name.Length + 1);
}
public static PropertyInfo GetPropertyInfo<TModel, TValue>(Expression<Func<TModel, TValue>> expression)
{
var member = expression.Body as MemberExpression;
if (member == null)
return null;
var propInfo = member.Member as PropertyInfo;
return propInfo;
}
private static string GetInputName(MethodCallExpression expression)
{
var expression1 = expression.Object as MethodCallExpression;
if (expression1 != null)
return GetInputName(expression1);
else
return expression.Object.ToString();
}
private static string GetTargetActionName(MethodInfo methodInfo)
{
if (methodInfo == null) throw new ArgumentNullException("methodInfo");
var name = methodInfo.Name;
if (methodInfo.IsDefined(typeof (NonActionAttribute), true))
{
throw new InvalidOperationException(string.Format(Helpers.MyFormat, "CannotCallNonAction {0}", name));
}
var actionNameAttribute = methodInfo.GetCustomAttributes(typeof (ActionNameAttribute), true).OfType<ActionNameAttribute>().FirstOrDefault();
if (actionNameAttribute != null)
return actionNameAttribute.Name;
if (methodInfo.DeclaringType.IsSubclassOf(typeof (AsyncController)))
{
if (name.EndsWith("Async", StringComparison.OrdinalIgnoreCase))
return name.Substring(0, name.Length - "Async".Length);
if (name.EndsWith("Completed", StringComparison.OrdinalIgnoreCase))
throw new InvalidOperationException(string.Format(Helpers.MyFormat, "CannotCallCompletedMethod: {0}", name));
}
return name;
}
private static void AddParameterValuesFromExpressionToDictionary(RouteValueDictionary rvd, MethodCallExpression call)
{
var parameters = call.Method.GetParameters();
if (parameters.Length <= 0)
return;
for (int index = 0; index < parameters.Length; ++index)
{
var expression = call.Arguments[index];
var constantExpression = expression as ConstantExpression;
var obj = constantExpression == null ? CachedExpressionCompiler.Evaluate(expression) : constantExpression.Value;
rvd.Add(parameters[index].Name, obj);
}
}
}
从您的角度来看,您现在可以这样做,必须传递默认值才能使 LINQ 表达式起作用,但它们不会被呈现
@(Url.Action<MyController>(x => x.MethodName(null, 0, 0)))
于 2012-04-26T07:42:06.590 回答