如何避免在不同位置使用相同键/值查询字符串的重复URL?

时间:2015-04-28 09:17:43

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

我正在使用Azure Redis缓存,我的密钥是请求网址。我有一个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)不同,它完全处理请求并在Azure Redis缓存服务器上保存不同的记录。如何解决这种情况?

2 个答案:

答案 0 :(得分:1)

这是我来得如此之快,任何改进都将受到赞赏,

    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());
    }

答案 1 :(得分:0)

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

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

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

MSDN: MVC5 Attribute Routing