8

Say I have a page that display search results. I search for stackoverflow and it returns 5000 results, 10 per page. Now I find myself doing this when building links on that page:

<%=Html.ActionLink("Page 1", "Search", new { query=ViewData["query"], page etc..%>
<%=Html.ActionLink("Page 2", "Search", new { query=ViewData["query"], page etc..%>
<%=Html.ActionLink("Page 3", "Search", new { query=ViewData["query"], page etc..%>
<%=Html.ActionLink("Next", "Search", new { query=ViewData["query"], page etc..%>

I dont like this, I have to build my links with careful consideration to what was posted previously etc..

What I'd like to do is

<%=Html.BuildActionLinkUsingCurrentActionPostData
        ("Next", "Search", new { Page = 1});

where the anonymous dictionary overrides anything currently set by previous action.

Essentially I care about what the previous action parameters were, because I want to reuse, it sounds simple, but start adding sort and loads of advance search options and it starts getting messy.

Im probably missing something obvious

4

8 回答 8

11

我在 HtmlHelper 中遇到了类似的问题;我想生成链接到当前页面的链接,对参数进行小幅调整(考虑增加页码)。因此,如果我有 URL /Item/?sort=Name&page=0,我希望能够创建指向同一页面的链接,但只需更改页面参数,并自动包含排序参数(即 /Item/?sort=名称&页面=1)。

我的解决方案是这样的(用于 HtmlHelper 扩展方法,但由于您几乎可以在 MVC 中的任何位置访问相同的数据,因此您可以轻松地调整它以适应您的使用):

private static RouteValueDictionary CreateRouteToCurrentPage(HtmlHelper html)
{
    RouteValueDictionary routeValues 
         = new RouteValueDictionary(html.ViewContext.RouteData.Values);

    NameValueCollection queryString 
         = html.ViewContext.HttpContext.Request.QueryString;

    foreach (string key in queryString.Cast<string>())
    {
        routeValues[key] = queryString[key];
    }

    return routeValues;
}

该方法的作用是获取当前请求的 RouteValueDictionary 并创建它的副本。然后它将在查询字符串中找到的每个查询参数添加到此路由。这样做是因为,出于某种原因,当前请求的 RouteValueDictionary 不包含它们(您认为它会包含它们,但事实并非如此)。

然后,您可以获取结果字典,仅修改其中的一部分,例如:

routeValues["page"] = 2;

然后将该字典提供给开箱即用的 HtmlHelper 方法,以便它们为您生成 URL/等。

于 2009-08-04T15:12:02.623 回答
1

每当您发现自己在视图中编写冗余代码时,请编写一个 helper。帮助器可以显式复制参数,就像您现在所做的那样,或者它可以迭代整个集合并自动复制。如果是我,我可能会选择前者。然后你可以只调用你的新助手,而不是每次建立链接时都重建参数。

于 2008-09-23T17:25:56.927 回答
1

对于您在这里实际尝试做的事情,我有点不确定。我认为您正在尝试自动化创建链接列表的过程,它们之间只有很小的变化。显然,在您的情况下,“页面”的 ID 号。

一种方法,虽然可能不是最好的,但像这样(我的代码使用了一个基本的和人为的产品列表,并且 ViewPage 和 PartialViewPage 都使用强类型模型):

在您的 ViewPage 上,您将添加如下代码:

<div id="product_list">
        <% foreach (TestMVC.Product product in ViewData.Model)
           { %>
            <% Html.RenderPartial("ProductEntry", product); %>
        <% } %>
</div>

你的部分视图,在我的例子中是“ProductEntry”,看起来像这样:

<div class="product">
    <div class="product-name">
        <%= Html.ActionLink(ViewData.Model.ProductName, "Detail", new { id = ViewData.Model.id })%>
    </div> 
    <div class="product-desc">
        <%= ViewData.Model.ProductDescription %>
    </div>       
</div>

我在该部分视图中所做的只是使用通过调用 Html.RenderPartial 从父视图传递的模型/视图数据

在您的父视图中,您可以在调用 Html.RenderPartial 之前修改模型对象上的参数,以便设置您感兴趣的特定值。

希望这可以帮助。

于 2008-09-23T19:57:57.250 回答
1

以下辅助方法就是这样做的:

    public static string EnhancedActionLink(this HtmlHelper helper, string linkText, string actionName, string controllerName, bool keepQueryStrings)
    {
        ViewContext context = helper.ViewContext;
        IDictionary<string, object> htmlAttributes = null;
        RouteValueDictionary routeValues = null;
        string actionLink = string.Empty;
        if (keepQueryStrings && context.RequestContext.HttpContext.Request.QueryString.Keys.Count > 0)
        {
            routeValues = new RouteValueDictionary(context.RouteData.Values);
            foreach (string key in context.RequestContext.HttpContext.Request.QueryString.Keys)
            {
                routeValues[key] = context.RequestContext.HttpContext.Request.QueryString[key];
            }
        }            
        actionLink = helper.ActionLink(linkText, actionName, controllerName, routeValues, htmlAttributes);
        return actionLink;
    }
于 2009-10-17T11:59:11.987 回答
0

花了几个小时尝试不同的解决方案后,只有这个对我有用: MVC ActionLink add all (optional) parameters from current url

于 2011-06-14T05:23:31.687 回答
0

看看这个,这是一个很好的例子: http: //nerddinnerbook.s3.amazonaws.com/Part8.htm

于 2010-12-03T13:22:46.677 回答
0

不完全是一个答案,但值得指出:如果您想要分页功能,请使用 PagedList Nuget 包(无需重新发明轮子)。以下链接提供了一个非常好的示例来说明如何使用它:ASP.NET 教程

这对您特别有用,因为在页面之间切换时查询字符串会保存在 URL 中。

于 2012-07-16T13:20:54.420 回答
0

Here's the actionlink extension


  public static class ActionLinkExtension
    {
        public static MvcHtmlString ActionLinkWithQueryString(this HtmlHelper helper, string linkText, string action, string controller, object routeValues)
        {
            var context = helper.ViewContext;

            var currentRouteValues = new RouteValueDictionary(context.RouteData.Values);
            foreach (string key in context.HttpContext.Request.QueryString.Keys)
            {
                currentRouteValues[key] = context.HttpContext.Request.QueryString[key];
            }

            var newRouteValues = new RouteValueDictionary(routeValues);

            foreach (var route in newRouteValues)
            {
                if (!currentRouteValues.ContainsKey(route.Key))
                {
                    currentRouteValues.Add(route.Key, route.Value);
                }
                else
                {
                    currentRouteValues[route.Key] = route.Value;
                }
            }

            return helper.ActionLink(linkText, action, controller, currentRouteValues, null);
        }

    }

于 2012-07-03T06:51:08.943 回答