首页 > 解决方案 > 更改 url 的查询字符串并保留路由

问题描述

在“更新”页面上,我有几个必须可点击的类别“标签”,它们将附加或删除 URL 中的特定标签。

因此,定义了几个标签并用 Umbraco 填充,现在每个标签都有一个 href,其中包含一个 UrlAction 到控制器中的方法。

<a href="@Url.Action("RedirectToIndex", "Blog", new { tags = tag} )"  class="filters__link @Umbraco.If(Model.IsTagActive(tag), "selected")"><i class="material-icons">local_offer</i>@tag</a></li>

我现在有一个带有硬编码网址的重定向操作:

 public ActionResult RedirectToIndex(string tags)
    {

        // build the URL string here but remember what the URL was previously??

        var url = "http://localhost:4166/updates?" + "tags=" + tags;

        return Redirect(url);
    }

我得到的 URL 字符串是一种奇怪'_internal/Blog/'的 URL,每次过滤器点击都会改变(当然)。

我想要发生的是,当用户点击一个标签时,url会随着相应的变化'updates?tags=firstTag&tags=secondTag'(基本上是重定向到他自己的地址,带有附加参数)等等,控制器的索引然后有相应的“过滤器”代码过滤博客并将它们与这些博客一起返回。我必须完全重新加载,因为包含所有博客的模型都来自 Umbraco,而且我看不到在不添加大量(不必要的)复杂代码的情况下访问它的方法。

public ActionResult Index(RenderModel model, [FromUri]string[] tags)
        {
           //filter code is here 
            return CurrentTemplate(blogModel);
        }

每当单击标签时,我都希望重新加载整个页面,而我唯一需要弄清楚的是如何构建 URL。

我已经查看了添加点击事件(服务器端),但随后我收到一个错误,该功能无法识别。

我觉得这个“问题”有多种解决方案,我正试图找出最好的选择。你能帮我吗?

标签: c#asp.net-mvcumbracoasp.net-mvc-5.2

解决方案


当我在构建一些包含过滤系统的网站时,我也有同样的需求,我写了一些扩展方法来帮助我完成这个过程:
以下是一些使用示例:

  • 想要更改参数的值(或添加新参数)?例如localhost/index?tag=one,您希望它成为localhost/index?tag=two&v=1然后使用Url.RouteWithSameQueryParams(new { tag = "two", v = 1 }).
  • 想要为参数添加值?例如localhost/index?tag=one,您希望它成为localhost/index?tag=one&tag=two&tag=three然后使用Url.RouteWithAddedValues("tag", "two", "three").
  • 您想删除参数的值吗?例如localhost/index?tag=one&tag=two,您希望它成为localhost/index?tag=one然后使用Url.RouteWithoutValue("tag", "two").

这是我的扩展类:

public static class UrlHelperExtensions
{

    public static string RouteWithSameQueryParams(this IUrlHelper url, object routeValues)
    {
        var resultRouteValues = new RouteValueDictionary(url.ActionContext.RouteData.Values);

        foreach (var queryValue in url.ActionContext.HttpContext.Request.Query)
        {
            resultRouteValues.Add(queryValue.Key, queryValue.Value);
        }

        if (routeValues == null)
            return url.RouteUrl(resultRouteValues);

        foreach (PropertyDescriptor descriptor in TypeDescriptor.GetProperties(routeValues))
        {
            if (resultRouteValues.ContainsKey(descriptor.Name))
            {
                resultRouteValues[descriptor.Name] = descriptor.GetValue(routeValues);
            }
            else
            {
                resultRouteValues.Add(descriptor.Name, descriptor.GetValue(routeValues));
            }
        }

        return url.RouteUrl(resultRouteValues);
    }

    public static string RouteWithoutValue(this IUrlHelper url, string param, string value)
    {
        var resultRouteValues = new RouteValueDictionary(url.ActionContext.RouteData.Values);

        foreach (var queryValue in url.ActionContext.HttpContext.Request.Query)
        {
            if (queryValue.Key.ToLower() == param)
            {
                if (value != null)
                    resultRouteValues.Add(queryValue.Key, new StringValues(queryValue.Value.Where(s => s != value).ToArray()));
            }
            else
                resultRouteValues.Add(queryValue.Key, queryValue.Value);
        }

        return url.RouteUrl(resultRouteValues);
    }

    public static string RouteWithAddedValues(this IUrlHelper url, string param, params string[] values)
    {
        var resultRouteValues = new RouteValueDictionary(url.ActionContext.RouteData.Values);

        foreach (var queryValue in url.ActionContext.HttpContext.Request.Query)
        {
            if (queryValue.Key.ToLower() == param)
            {
                var vals = new List<string>(queryValue.Value);
                vals.AddRange(values);
                resultRouteValues.Add(queryValue.Key, new StringValues(vals.ToArray()));
            }
            else
            {
                resultRouteValues.Add(queryValue.Key, queryValue.Value);
            }
        }

        if (!resultRouteValues.ContainsKey(param))
        {
            resultRouteValues.Add(param, new StringValues(values));
        }

        return url.RouteUrl(resultRouteValues);
    }

}

推荐阅读