ASP.NET MVC - 创建操作链接保留查询字符串

时间:2017-02-03 10:40:53

标签: c# asp.net-mvc razor asp.net-core asp.net-core-mvc

我目前正在为ASP.NET Core MVC编写自己的分页列表。

在创建以下内容时我很难:

我想创建一个UrlHelper扩展方法: Url.PageLink(int page,int pageSize)

在该扩展方法中,我想返回一个链接,该链接重用控制器,操作,查询字符串的所有当前值,此外它还应该在查询字符串中添加/更新页面,pageSize值。

问题: 从哪里获取UrlHelper对象中的当前控制器和操作? 重建查询字符串的最佳方法是什么? 我可以在这里看到url.ActionContext.HttpContext.Request.QueryString ...但我真的必须手动重建它吗?或者是否存在类似AddQueryStringValue(int key,object value)的东西?

非常感谢! 西蒙

2 个答案:

答案 0 :(得分:1)

现在就这样做了:

public static class UrlHelperExtensions
{
    public static string Page(this IUrlHelper url, int page, int pageSize)
    {
        //Reuse existing route values
        RouteValueDictionary resultRouteValues = new RouteValueDictionary(url.ActionContext.RouteData.Values);

        //Add existing values from query string
        foreach (var queryValue in url.ActionContext.HttpContext.Request.Query)
        {
            if(resultRouteValues.ContainsKey(queryValue.Key))
                continue;

            resultRouteValues.Add(queryValue.Key, queryValue.Value);
        }

        //Set or add values for PagedList input model
        resultRouteValues[nameof(PagedListInputModel.Page)] = page;
        resultRouteValues[nameof(PagedListInputModel.PageSize)] = pageSize;

        return url.RouteUrl(resultRouteValues);
    }
}

为页面列表值创建了一个单独的输入模型“PagedListInputModel”...这样我可以确保我可以在所有地方重用它,而不必确保所有地方都包含page和pageSize属性需要具有正确名称的视图模型。

欢迎任何反馈。

答案 1 :(得分:1)

该问题要求Asp.Net Core。我试图在MVC 5上使用shturm的答案而无法使其工作。我采用了相同的概念并将其改为与MVC 5一起工作。如果有人需要这个版本,我会在这里发布。我还添加了更改动作和控制器的功能。

    /// <summary>
    /// Get URL with substituted values while preserving query string.
    /// </summary>
    /// <param name="helper">The url helper object we are extending.</param>
    /// <param name="action">The action we want to direct to.</param>
    /// <param name="controller">The controller we want to direct to.</param>
    /// <param name="substitutes">Query string parameters or route data paremers. E.g. new { action="Index", sort = "asc"}</param>
    /// <returns>The route string.</returns>
    public static String ActionWithOriginalQueryString(this UrlHelper helper, String action, String controller, object substitutes)
    {            
        RouteValueDictionary routeData = new RouteValueDictionary(helper.RequestContext.RouteData.Values);
        NameValueCollection queryString = helper.RequestContext.HttpContext.Request.QueryString;

        //add query string parameters to the route data
        foreach (var param in queryString.AllKeys)
        {
            if (!string.IsNullOrEmpty(queryString[param]))
            {
                //rd[param.Key] = qs[param.Value]; // does not assign the values!
                routeData.Add(param, queryString[param]);
            }
        }

        // override parameters we're changing in the route data
        //The unmatched parameters will be added as query string.
        foreach (PropertyDescriptor property in TypeDescriptor.GetProperties(substitutes.GetType()))
        {
            var value = property.GetValue(substitutes);
            if (string.IsNullOrEmpty(value?.ToString()))
            {
                routeData.Remove(property.Name);
            }
            else
            {
                routeData[property.Name] = value;
            }
        }

        //Set the controller and the action.
        routeData["controller"] = controller;
        routeData["action"] = action;

        //Return the route.
        return helper.RouteUrl(routeData);
    }