Search code examples
c#asp.net-mvcazureasp.net-web-apiazure-redis-cache

How to avoid duplicate urls with same key/value query-string at different places?


I am using Azure Redis cache with my key is the request url. I have a web-api2 / mvc5 application which returns the cached result from Redis server if key with request url exist there otherwise it will process the request and save the result in Azure Redis cache server. I have mobile clients for IOS/Android as well as javascript. The problem is that some time my url look like,

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=

The above url points to the same resource. It should return the same response(cached response if exist) but since key(url) is different it process the request completely and save a different record on Azure Redis cache server. How to solve this scenario?


Solution

  • Here is what I have came so fast, any improvement will be appreciated,

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