c# - 检查 2 个 URL 是否相等

标签 c# asp.net

有没有一种方法可以测试 2 个 URL 是否相等,即指向同一个地方? 我不是在谈论具有不同域名的 2 个指向相同 IP 地址的 URL,而是例如,指向相同 .aspx 页面的 2 个 URL:

等于这些:

注意/假设

  1. QueryString 值被忽略
  2. ASP.NET(首选 C#)
  3. Default.aspx 是默认页面

----更新----

这是一种非常粗略的方法,用于测试 URL 以查看是否与当前 URL 匹配: 我尝试使用本地 URL 和检查 URL 创建一个 new Uri(),但不知道它是否有效,于是走下了字符串检查途径。 如果 URL 以“HTTP”开头,则 SiteMapProvider 的实现会跳过此步骤,因为这假定为外部 URL。由于我有一个始终确保相对路径的 SaaS 框架(因为这些可以位于不同的子域中),因此更容易剥离内容。

对优化有什么意见吗?我想一开始我们可以传入一个包含当前 URL 的变量?不确定多次调用 HttpContext.Current.Request.Url.LocalPath 的开销?

/// <summary>
/// Assumes URL is relative aspx page or folder path
/// </summary>
/// <param name="url"></param>
/// <returns></returns>
public static bool CurrentURLMatch(string url)
{
    string localURL = HttpContext.Current.Request.Url.LocalPath;
    
    if (HttpContext.Current.Request.Url.Host == "localhost")
    {
        localURL = localURL.Substring(localURL.IndexOf('/') + 1);
        localURL = localURL.Substring(localURL.IndexOf('/'));
    }
    string compareURL = url.ToLower();

    // Remove QueryString Values
    if (localURL.Contains("?"))
    {
        localURL = localURL.Split('?')[0];
    }

    if (compareURL.Contains("?"))
    {
        compareURL = compareURL.Split('?')[0];
    }

    if (localURL.Contains("#"))
    {
        localURL = localURL.Split('#')[0];
    }
    if (compareURL.Contains("?"))
    {
        compareURL = compareURL.Split('#')[0];
    }

    // Prepare End of Local URL
    if (!localURL.Contains("aspx"))
    {
        if (!localURL.EndsWith("/"))
        {
            localURL = String.Concat(localURL, "/");
        }
    }

    // Prepare End of Compare URL
    if (!compareURL.Contains("aspx"))
    {
        if (!compareURL.EndsWith("/"))
        {
            compareURL = String.Concat(localURL, "/");
        }
    }

    if (localURL.EndsWith(@"/"))
    {
        localURL = String.Concat(localURL, "Default.aspx");
    }

    if (compareURL.EndsWith(@"/"))
    {
        compareURL = String.Concat(compareURL, "Default.aspx");
    }

    if (compareURL.Contains(@"//"))
    {
        compareURL = compareURL.Replace(@"//", String.Empty);
        compareURL = compareURL.Substring(compareURL.IndexOf("/") + 1);
    }

    compareURL = compareURL.Replace("~", String.Empty);

    if (localURL == compareURL)
    {
        return true;
    }

    return false;
}

最佳答案

为了记录,这里是http://en.wikipedia.org/wiki/URL%5Fnormalization的翻译到 C#:

using System;
using System.Web;

namespace UrlNormalizationTest
{
    public static class UrlNormalization
    {
        public static bool AreTheSameUrls(this string url1, string url2)
        {
            url1 = url1.NormalizeUrl();
            url2 = url2.NormalizeUrl();
            return url1.Equals(url2);
        }

        public static bool AreTheSameUrls(this Uri uri1, Uri uri2)
        {
            var url1 = uri1.NormalizeUrl();
            var url2 = uri2.NormalizeUrl();
            return url1.Equals(url2);
        }

        public static string[] DefaultDirectoryIndexes = new[]
            {
                "default.asp",
                "default.aspx",
                "index.htm",
                "index.html",
                "index.php"
            };

        public static string NormalizeUrl(this Uri uri)
        {
            var url = urlToLower(uri);
            url = limitProtocols(url);
            url = removeDefaultDirectoryIndexes(url);
            url = removeTheFragment(url);
            url = removeDuplicateSlashes(url);
            url = addWww(url);
            url = removeFeedburnerPart(url);
            return removeTrailingSlashAndEmptyQuery(url);
        }

        public static string NormalizeUrl(this string url)
        {
            return NormalizeUrl(new Uri(url));
        }

        private static string removeFeedburnerPart(string url)
        {
            var idx = url.IndexOf("utm_source=", StringComparison.Ordinal);
            return idx == -1 ? url : url.Substring(0, idx - 1);
        }

        private static string addWww(string url)
        {
            if (new Uri(url).Host.Split('.').Length == 2 && !url.Contains("://www."))
            {
               return url.Replace("://", "://www.");
            }
            return url;
        }

        private static string removeDuplicateSlashes(string url)
        {
            var path = new Uri(url).AbsolutePath;
            return path.Contains("//") ? url.Replace(path, path.Replace("//", "/")) : url;
        }

        private static string limitProtocols(string url)
        {
            return new Uri(url).Scheme == "https" ? url.Replace("https://", "http://") : url;
        }

        private static string removeTheFragment(string url)
        {
            var fragment = new Uri(url).Fragment;
            return string.IsNullOrWhiteSpace(fragment) ? url : url.Replace(fragment, string.Empty);
        }

        private static string urlToLower(Uri uri)
        {
            return HttpUtility.UrlDecode(uri.AbsoluteUri.ToLowerInvariant());
        }

        private static string removeTrailingSlashAndEmptyQuery(string url)
        {
            return url
                    .TrimEnd(new[] { '?' })
                    .TrimEnd(new[] { '/' });
        }

        private static string removeDefaultDirectoryIndexes(string url)
        {
            foreach (var index in DefaultDirectoryIndexes)
            {
                if (url.EndsWith(index))
                {
                    url = url.TrimEnd(index.ToCharArray());
                    break;
                }
            }
            return url;
        }
    }
}

通过以下测试:

using NUnit.Framework;
using UrlNormalizationTest;

namespace UrlNormalization.Tests
{
    [TestFixture]
    public class UnitTests
    {
        [Test]
        public void Test1ConvertingTheSchemeAndHostToLowercase()
        {
            var url1 = "HTTP://www.Example.com/".NormalizeUrl();
            var url2 = "http://www.example.com/".NormalizeUrl();

            Assert.AreEqual(url1, url2);
        }

        [Test]
        public void Test2CapitalizingLettersInEscapeSequences()
        {
            var url1 = "http://www.example.com/a%c2%b1b".NormalizeUrl();
            var url2 = "http://www.example.com/a%C2%B1b".NormalizeUrl();

            Assert.AreEqual(url1, url2);
        }

        [Test]
        public void Test3DecodingPercentEncodedOctetsOfUnreservedCharacters()
        {
            var url1 = "http://www.example.com/%7Eusername/".NormalizeUrl();
            var url2 = "http://www.example.com/~username/".NormalizeUrl();

            Assert.AreEqual(url1, url2);
        }

        [Test]
        public void Test4RemovingTheDefaultPort()
        {
            var url1 = "http://www.example.com:80/bar.html".NormalizeUrl();
            var url2 = "http://www.example.com/bar.html".NormalizeUrl();

            Assert.AreEqual(url1, url2);
        }

        [Test]
        public void Test5AddingTrailing()
        {
            var url1 = "http://www.example.com/alice".NormalizeUrl();
            var url2 = "http://www.example.com/alice/?".NormalizeUrl();

            Assert.AreEqual(url1, url2);
        }

        [Test]
        public void Test6RemovingDotSegments()
        {
            var url1 = "http://www.example.com/../a/b/../c/./d.html".NormalizeUrl();
            var url2 = "http://www.example.com/a/c/d.html".NormalizeUrl();

            Assert.AreEqual(url1, url2);
        }

        [Test]
        public void Test7RemovingDirectoryIndex1()
        {
            var url1 = "http://www.example.com/default.asp".NormalizeUrl();
            var url2 = "http://www.example.com/".NormalizeUrl();

            Assert.AreEqual(url1, url2);
        }

        [Test]
        public void Test7RemovingDirectoryIndex2()
        {
            var url1 = "http://www.example.com/default.asp?id=1".NormalizeUrl();
            var url2 = "http://www.example.com/default.asp?id=1".NormalizeUrl();

            Assert.AreEqual(url1, url2);
        }

        [Test]
        public void Test7RemovingDirectoryIndex3()
        {
            var url1 = "http://www.example.com/a/index.html".NormalizeUrl();
            var url2 = "http://www.example.com/a/".NormalizeUrl();

            Assert.AreEqual(url1, url2);
        }

        [Test]
        public void Test8RemovingTheFragment()
        {
            var url1 = "http://www.example.com/bar.html#section1".NormalizeUrl();
            var url2 = "http://www.example.com/bar.html".NormalizeUrl();

            Assert.AreEqual(url1, url2);
        }

        [Test]
        public void Test9LimitingProtocols()
        {
            var url1 = "https://www.example.com/".NormalizeUrl();
            var url2 = "http://www.example.com/".NormalizeUrl();

            Assert.AreEqual(url1, url2);
        }

        [Test]
        public void Test10RemovingDuplicateSlashes()
        {
            var url1 = "http://www.example.com/foo//bar.html".NormalizeUrl();
            var url2 = "http://www.example.com/foo/bar.html".NormalizeUrl();

            Assert.AreEqual(url1, url2);
        }

        [Test]
        public void Test11AddWww()
        {
            var url1 = "http://example.com/".NormalizeUrl();
            var url2 = "http://www.example.com".NormalizeUrl();

            Assert.AreEqual(url1, url2);
        }

        [Test]
        public void Test12RemoveFeedburnerPart()
        {
            var url1 = "http://site.net/2013/02/firefox-19-released/?utm_source=rss&utm_medium=rss&utm_campaign=firefox-19-released".NormalizeUrl();
            var url2 = "http://site.net/2013/02/firefox-19-released".NormalizeUrl();

            Assert.AreEqual(url1, url2);
        }
    }
}

关于c# - 检查 2 个 URL 是否相等,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1222610/

相关文章:

c# - 约会时间?串起来

asp.net - 从代码隐藏中查找 FormView 中的控件时出现问题

c# - 在数组中查找值的索引

asp.net - 为什么这个标签不居中?

c# - 深度复制 ASP.NET GridView

C# SqlCommand 命名约定

c# - 如何在 aspx 文件中调用中继器中的函数?

c# - 全局引用命名空间?

c# - 在 C# 中从图像中获取 RGB 数组

c# - Dynamics CRM Web api 401 获取 Oauth token 后未经授权