ASP.NET MVC:通过所有ActionLinks传播查询参数的正确方法

时间:2012-02-25 08:20:06

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

在我的应用程序中,key查询字符串参数可用于授予对某些操作/视图的访问权限 现在我希望所有ActionLinks和Forms自动包含此参数(如果存在于当前查询字符串中)。

这样做的正确方法是什么?

我问的是正确的方法,因为我看到了几种建议以某种方式改变视图的解决方案(替代扩展方法/助手,手动参数传递)。这不是我要找的解决方案。

更新
最终解决方案(基于MikeSW的anwer):https://gist.github.com/1918893

6 个答案:

答案 0 :(得分:10)

你可以用路线做,但你需要更多的基础设施。像这样的东西

public class RouteWithKey:Route
{
  //stuff omitted
   public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
   {
     values.Add("key", requestContext.HttpContext.Request.QueryString["key"]);   
    var t = base.GetVirtualPath(requestContext, values);        
        return t;
    } 
}

当然你需要从请求参数中检索密钥并处理密钥是查询中第二个参数的情况,但是这个apporach将自动添加密钥到通过正常的as.net mvc构建的每个utel助手

我碰巧为应用程序使用自定义路由,出于不同的目的,但我已经使用上面的代码测试并添加了参数,所以至少在我的项目中似乎工作正常。

答案 1 :(得分:2)

如何将密钥添加到路由值。

{控制器} / {行动} / {键}

每当一个url包含一个key = somevalue的查询字符串时,该网址就会显示为

主页/索引/ someValue中,

现在,默认情况下,所有操作链接和相关网址都会包含此内容。

答案 2 :(得分:0)

嗨,对于您描述的情况,您可以轻松使用Cookie。使用name键创建一个cookie,其值与key URL参数的值相同。现在,您可以使用有效cookie的存在与否来提供或拒绝对您的用户的访问,而不是存在或不存在关键参数。

您可以使用Response.Cookies

访问Cookie

如果您仍想更改所有Form和ActionLink帮助程序,那么您可以使用额外的key参数创建自己的帮助程序,在内部调用MVC帮助程序,并在任何地方使用自定义帮助程序。查看here以编写自定义帮助程序

答案 3 :(得分:0)

为此,我写了一个名为“ActionLinkBack”的HtmlHelper扩展。这些方法将动作链接组合回同一个控制器并将现有路由值与指定的任何新路由值合并。

public static HtmlString ActionLinkBack(this System.Web.Mvc.HtmlHelper htmlHelper, string linkText, object routeValues)
{
    return ActionLinkBack(htmlHelper, linkText, new RouteValueDictionary(routeValues), new RouteValueDictionary());
}

public static HtmlString ActionLinkBack(this System.Web.Mvc.HtmlHelper htmlHelper, string linkText, object routeValues, object htmlAttributes)
{
    return ActionLinkBack(htmlHelper, linkText, new RouteValueDictionary(routeValues), new RouteValueDictionary(htmlAttributes));
}

public static HtmlString ActionLinkBack(this System.Web.Mvc.HtmlHelper htmlHelper, string linkText, RouteValueDictionary routeValues)
{
    return ActionLinkBack(htmlHelper, linkText, routeValues, new RouteValueDictionary());
}

public static HtmlString ActionLinkBack(this System.Web.Mvc.HtmlHelper htmlHelper, string linkText, RouteValueDictionary routeValues, IDictionary<string, object> htmlAttributes)
{
    // Build a new dictionary of route values based on the previous set
    var newRouteValues = new RouteValueDictionary(htmlHelper.ViewContext.RouteData.Values);

    // Retain current querystring parameters
    var queryString = htmlHelper.ViewContext.HttpContext.Request.QueryString;
    if (queryString.Count > 0)
    {
        foreach (string key in queryString.Keys)
        {
            newRouteValues[key] = queryString[key];
        }
    }

    // Add and override entries from the list of new route values
    if (routeValues != null)
    {
        foreach (var routeValueItem in routeValues)
        {
            newRouteValues[routeValueItem.Key] = routeValueItem.Value;
        }
    }

    return new HtmlString(htmlHelper.ActionLink(linkText, null, newRouteValues, htmlAttributes).ToHtmlString());
}

在我的可重复使用的“页面导航器”视图中,我使用扩展来编写上一页,下一页和单页链接:

@Html.ActionLinkBack("Next", new { page = (int)ViewData["Page"] + 1 }, new { @class = "navigationLink" })

答案 4 :(得分:-1)

拥有一个控制授权的查询字符串参数是一个坏主意恕我直言。什么阻止我将此参数添加到我的不包含的网址?

实现授权的首选方法是使用角色(http://msdn.microsoft.com/en-us/library/system.web.security.roleprovider.aspx)。

答案 5 :(得分:-1)

最简单的方法是以这种方式将“key”参数放在所有Url.Action和Html.ActionLink中:

@Url.Action("MyAction", "MyController", new { key = Request["key"] })

如果Request["key"]为空,则跳过querystring参数。