【问题标题】:How to avoid duplicate urls with same key/value query-string at different places?如何避免在不同位置具有相同键/值查询字符串的重复 url?
【发布时间】:2015-04-28 19:56:59
【问题描述】:

我正在使用 Azure Redis 缓存,我的键是请求 url。我有一个 web-api2 / mvc5 应用程序,如果存在带有请求 url 的键,它将从 Redis 服务器返回缓存结果,否则它将处理请求并将结果保存在 Azure Redis 缓存服务器中。我有 IOS/Android 和 javascript 的移动客户端。问题是有时我的网址看起来像,

http://example.com/MyPath/?b=2&a=1&c=
http://example.com/MyPath/?b=2&a=1&c
http://example.com/MyPath/?a=1&b=2
http://example.com/MyPath/?c=&a=1&b=2
http://example.com/MyPath/?a=1&b=2
http://example.com/MyPath/?a=1&b=2&c=

上面的 url 指向同一个资源。它应该返回相同的响应(如果存在缓存响应),但由于 key(url) 不同,它会完全处理请求并在 Azure Redis 缓存服务器上保存不同的记录。如何解决这种情况?

【问题讨论】:

    标签: c# asp.net-mvc azure asp.net-web-api azure-redis-cache


    【解决方案1】:

    使用 MVC 路由将为您的 URL 提供标准格式。

    您将能够在 ASP.NET 中使用默认的 html 帮助程序,例如 @Html.Action("MethodName","Controller",new { a=1, b=2 })

    您可以在 RouteConfig.cs 类中指定自定义路由模板(默认在 app_start 中),也可以使用属性路由。

    MSDN: MVC5 Attribute Routing

    【讨论】:

      【解决方案2】:

      这就是我来得如此之快,任何改进将不胜感激,

          private static string SanitizeUrl(string url)
          {
              var uri = new Uri(url);
              var path = uri.GetLeftPart(UriPartial.Path);
              path += path.EndsWith("/") ? "" : "/";
              var query = uri.ParseQueryString();
              var dict = new SortedDictionary<string, string>(query.AllKeys
                  .Where(k => !string.IsNullOrWhiteSpace(query[k]))
                  .ToDictionary(k => k, k => query[k]));
              return (path + ToQueryString(dict)).ToLower();
          }
      
          private static string ToQueryString(SortedDictionary<string, string> dict)
          {
              var items = new List<string>();
              foreach (var entry in dict)
              {
                  items.Add(string.Concat(entry.Key, "=", Uri.EscapeUriString(entry.Value)));
              }
              return (items.Count > 0 ? "?" : "") + string.Join("&", items.ToArray());
          }
      

      【讨论】:

      • 仅供参考 - HttpUtility.ParseQueryString("") 返回一个 NameValueCollection,它实际上是一个 HttpValueCollection。在 HttpValueCollection 上调用 .ToString 将返回格式化的查询字符串。示例 -> pastebin.com/A0DwH9w5
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-30
      • 2013-04-05
      • 1970-01-01
      • 2011-04-29
      相关资源
      最近更新 更多