【问题标题】:make in the URL the controllername visible but not the parameters在 URL 中使控制器名称可见,但参数不可见
【发布时间】:2012-04-26 07:16:20
【问题描述】:

有没有办法在 MVC3 中创建一个仅包含控制器名称但不包含其参数的 URL 我做了一个@url.Action("action","controller",the model) 我希望用户看到; '/controller/action' 不是 '/controller/action?....&..&..' 我不知道该怎么做。

【问题讨论】:

    标签: asp.net-mvc-3 url asp.net-mvc-routing


    【解决方案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)))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-06-14
      • 2011-04-06
      • 1970-01-01
      • 2019-03-14
      • 2021-02-15
      • 2012-05-30
      相关资源
      最近更新 更多