对于使用 publicsuffix.org 的域名解析器代码,将降级 Linq 转换为普通 C# .NET 2.0

发布于 2024-08-07 00:26:44 字数 1549 浏览 4 评论 0原文

根据这个答案 从 URL 获取子域,我正在尝试使用code.google.com/p/domainname-parser/ 将使用 publicsuffix.org 中的公共后缀列表来获取用于管理我的 cookie 集合的子域和域。

目前,Domainname-parser 是我在互联网上找到的唯一实现 publicsuffix.org 列表的 .NET 代码。

为了使用域名解析器,我想对源代码进行更改,以便它能够:

  1. 在 .NET 2.0 中使用
  2. Accept Uri 对象将主机解析为子域、域和 TLD。
  3. 如果 LastModified 更改,将使用 WebRequest 和 WebResponse 自动从 publicsuffix.org 下载最新列表。

因此它将变得更加可用并且始终更新。 (2) 和 (3) 不会成为问题,但 (1) 是我现在的重点。

当前的域名解析器是 v1.0,构建为使用代码中使用 Linq 的 .NET 3.5。为了使其兼容 .NET 2.0,我需要将 Linq 代码转换为非 Linq,这让我了解公共后缀列表规则。这就是正常、通配符和例外规则。但是我不了解 Linq 以及如何将其转换回正常方式。

转换器工具可能很有用,但更好的是我逐行检查和修改它。

现在我的问题是如何转换它?例如,来自 DomainNames 类中的 FindMatchingTLDRule 方法的代码:

//  Try to match an wildcard rule:
var wildcardresults = from test in TLDRulesCache.Instance.TLDRuleList
                      where
                        test.Name.Equals(checkAgainst, StringComparison.InvariantCultureIgnoreCase)
                        &&
                        test.Type == TLDRule.RuleType.Wildcard
                      select
                        test;

还有这个:

        var results = from match in ruleMatches
                      orderby match.Name.Length descending
                      select match;

要遵循的简单指南是什么? 或者任何免费工具可以将上面这句话转换为.NET 2.0 中的普通 C# 代码。

我相信不涉及数据库,只是涉及它们处理集合的方式。

我还尝试联系域名解析器所有者来改进代码并帮助我解决这个问题。

感谢

CallMeLaNN

Based on this answer Get the subdomain from a URL, I am trying to use code.google.com/p/domainname-parser/ that will use Public Suffix List from publicsuffix.org to get subdomain and domain for managing my cookie collection.

In the current moment, Domainname-parser is the only .NET code I found in the internet that implement list from publicsuffix.org.

In order to use Domainname-parser I want to make a changes to the source code so that it would be able to:

  1. Use in .NET 2.0
  2. Accept Uri object to parse the Host into subdomain, domain and TLD.
  3. Will auto download the latest list from the publicsuffix.org by using WebRequest and WebResponse if LastModified is changed.

So it will become more usable and always updated. (2) and (3) would not be a problem but (1) is my focus now.

The current Domainname-parser is v1.0, build to use .NET 3.5 that using Linq in the code. To make it compatible to .NET 2.0, I need to convert the Linq codes to non-Linq and it makes me to understand the Public Suffix List rules. That is Normal, Wildcard and Exception rule. However I don't have knowledge about Linq and how it can be converted back to the normal way.

Converter tools might be useful but the better is I review and modify it line by line.

Now my question is how can I convert it? Eg codes from FindMatchingTLDRule method in DomainNames class:

//  Try to match an wildcard rule:
var wildcardresults = from test in TLDRulesCache.Instance.TLDRuleList
                      where
                        test.Name.Equals(checkAgainst, StringComparison.InvariantCultureIgnoreCase)
                        &&
                        test.Type == TLDRule.RuleType.Wildcard
                      select
                        test;

and also this:

        var results = from match in ruleMatches
                      orderby match.Name.Length descending
                      select match;

What is the simple guide line to follow?
or any free tools to convert this one sentence above to the normal C# codes in .NET 2.0.?

I believe that no database involved, just in the way they deals with collections.

I also trying to contact the domainname-parser owner to improve the codes and help me to solve this.

Thanks

CallMeLaNN

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

白色秋天 2024-08-14 00:26:44

好的,为了回应评论,这里有一个返回列表的版本。

public List<TLDRule> MatchWildcards(IEnumerable<TLDRule> rules,
                                    string checkAgainst)
{
    List<TLDRule> ret = new List<TLDRule>();
    foreach (TLDRule rule in rules)
    {
        if (rule.Name.Equals(checkAgainst, 
                             StringComparison.InvariantCultureIgnoreCase)
            && rule.Type == TLDRule.RuleType.Wildcard)
        {
            ret.Add(rule);
        }
    }
    return ret;
}

Then:

List<TLDRule> wildcardresults = MatchWildcards(
    TLDRulesCache.Instance.TLDRuleList, checkAgainst);

但是,如果您要转换大量代码(并且如果您确实必须要转换它 - 见下文),您确​​实应该了解有关 LINQ 的更多信息。您最终肯定会使用它,如果您了解它的工作原理,您将能够更好地弄清楚如何进行转换。最近的 C# 书籍涵盖了 LINQ;如果您有我自己的书(C# in Depth),那么第 8-11 章将涵盖您需要了解的有关 LINQ to Objects 的所有内容。

如果您能够使用 VS2008 但仅目标 .NET 2.0,另一种选择是使用 LINQBridge 是 .NET 2.0 的 LINQ to Objects 的重新实现...现在是 开源 :)

Okay, in response to comments, here's a version returning a list.

public List<TLDRule> MatchWildcards(IEnumerable<TLDRule> rules,
                                    string checkAgainst)
{
    List<TLDRule> ret = new List<TLDRule>();
    foreach (TLDRule rule in rules)
    {
        if (rule.Name.Equals(checkAgainst, 
                             StringComparison.InvariantCultureIgnoreCase)
            && rule.Type == TLDRule.RuleType.Wildcard)
        {
            ret.Add(rule);
        }
    }
    return ret;
}

Then:

List<TLDRule> wildcardresults = MatchWildcards(
    TLDRulesCache.Instance.TLDRuleList, checkAgainst);

However, if you're converting a lot of code (and if you really have to convert it - see below) you should really learn more about LINQ. You're pretty much bound to use it eventually, and if you understand how it works you'll be in a much better position to work out how to do the conversion. Most recent C# books cover LINQ; if you have my own book (C# in Depth) then chapters 8-11 will cover everything you need to know for LINQ to Objects.

Another alternative if you're able to use VS2008 but just target .NET 2.0 is to use LINQBridge which is a reimplementation of LINQ to Objects for .NET 2.0... and it's now open source :)

她说她爱他 2024-08-14 00:26:44

感谢乔恩·斯基特(Jon Skeet)对我的帮助很大。它运行得很好,所有单元测试都成功通过。

在这里,我想与任何想要在 .NET 2.0 中使用域名解析器的人分享答案

1 将此代码(DomainName.cs)更改

            //  Try to match an exception rule:
            var exceptionresults = from test in TLDRulesCache.Instance.TLDRuleList
                                   where
                                     test.Name.Equals(checkAgainst, StringComparison.InvariantCultureIgnoreCase)
                                     &&
                                     test.Type == TLDRule.RuleType.Exception
                                   select
                                     test;

            //  Try to match an wildcard rule:
            var wildcardresults = from test in TLDRulesCache.Instance.TLDRuleList
                                  where
                                    test.Name.Equals(checkAgainst, StringComparison.InvariantCultureIgnoreCase)
                                    &&
                                    test.Type == TLDRule.RuleType.Wildcard
                                  select
                                    test;

            //  Try to match a normal rule:
            var normalresults = from test in TLDRulesCache.Instance.TLDRuleList
                                where
                                  test.Name.Equals(checkAgainst, StringComparison.InvariantCultureIgnoreCase)
                                  &&
                                  test.Type == TLDRule.RuleType.Normal
                                select
                                  test;

为:

List<TLDRule> exceptionresults = MatchRule(TLDRulesCache.Instance.TLDRuleList, checkAgainst, TLDRule.RuleType.Exception);
List<TLDRule> wildcardresults = MatchRule(TLDRulesCache.Instance.TLDRuleList, checkAgainst, TLDRule.RuleType.Wildcard);
List<TLDRule> normalresults = MatchRule(TLDRulesCache.Instance.TLDRuleList, checkAgainst, TLDRule.RuleType.Normal);

    private static List<TLDRule> MatchRule(List<TLDRule> rules, string checkAgainst, TLDRule.RuleType ruleType)
    {
        List<TLDRule> matchedResult = new List<TLDRule>();
        foreach (TLDRule rule in rules)
        {
            if (rule.Name.Equals(checkAgainst, StringComparison.InvariantCultureIgnoreCase)
                && rule.Type == ruleType)
            {
                matchedResult.Add(rule);
            }
        }
        return matchedResult;
    }

2 将此:更改

        //  Sort our matches list (longest rule wins, according to :
        var results = from match in ruleMatches
                      orderby match.Name.Length descending
                      select match;

        //  Take the top result (our primary match):
        TLDRule primaryMatch = results.Take(1).SingleOrDefault();

为此

        TLDRule primaryMatch = null;
        if (ruleMatches.Count > 0)
        {
            // match2 CompareTo match1 (reverse order) to make the descending
            ruleMatches.Sort(delegate(TLDRule match1, TLDRule match2) { return match2.Name.Length.CompareTo(match1.Name.Length); });
            primaryMatch = ruleMatches[0];
        }

3 将此(TLDRulesCache.cs)

            IEnumerable<TLDRule> lstTLDRules = from ruleString in lstTLDRuleStrings
                                               where
                                               !ruleString.StartsWith("//", StringComparison.InvariantCultureIgnoreCase)
                                               &&
                                               !(ruleString.Trim().Length == 0)
                                               select new TLDRule(ruleString);

更改为此

List<TLDRule> lstTLDRules = ListTLDRule(lstTLDRuleStrings);

    private static List<TLDRule> ListTLDRule(List<string> lstTLDRuleStrings)
    {
        List<TLDRule> lstTLDRule = new List<TLDRule>();
        foreach (string ruleString in lstTLDRuleStrings)
        {
            if (!ruleString.StartsWith("//", StringComparison.InvariantCultureIgnoreCase)
                &&
                !(ruleString.Trim().Length == 0))
            {
                lstTLDRule.Add(new TLDRule(ruleString));
            }
        }
        return lstTLDRule;
    }

其他一些是 像“var exceptionresults”中这样的小事情:

List<string> lstDomainParts = domainString.Split('.').ToList<string>();

更改为:

List<string> lstDomainParts = new List<string>(domainString.Split('.'));

和删除 .ToList()

将使用 exceptionresults.ToList() 来获取列表。由于“varExceptionresults”更改为“ListExceptionresults”,因此应删除 .ToList() 。

叫我拉恩

Thanks to Jon Skeet that really helps me. It works very well and all UnitTest passed successfully.

Here I want to share the answer to anybody want to use Domainname-parser in .NET 2.0

1 Change this codes (DomainName.cs)

            //  Try to match an exception rule:
            var exceptionresults = from test in TLDRulesCache.Instance.TLDRuleList
                                   where
                                     test.Name.Equals(checkAgainst, StringComparison.InvariantCultureIgnoreCase)
                                     &&
                                     test.Type == TLDRule.RuleType.Exception
                                   select
                                     test;

            //  Try to match an wildcard rule:
            var wildcardresults = from test in TLDRulesCache.Instance.TLDRuleList
                                  where
                                    test.Name.Equals(checkAgainst, StringComparison.InvariantCultureIgnoreCase)
                                    &&
                                    test.Type == TLDRule.RuleType.Wildcard
                                  select
                                    test;

            //  Try to match a normal rule:
            var normalresults = from test in TLDRulesCache.Instance.TLDRuleList
                                where
                                  test.Name.Equals(checkAgainst, StringComparison.InvariantCultureIgnoreCase)
                                  &&
                                  test.Type == TLDRule.RuleType.Normal
                                select
                                  test;

into this:

List<TLDRule> exceptionresults = MatchRule(TLDRulesCache.Instance.TLDRuleList, checkAgainst, TLDRule.RuleType.Exception);
List<TLDRule> wildcardresults = MatchRule(TLDRulesCache.Instance.TLDRuleList, checkAgainst, TLDRule.RuleType.Wildcard);
List<TLDRule> normalresults = MatchRule(TLDRulesCache.Instance.TLDRuleList, checkAgainst, TLDRule.RuleType.Normal);

    private static List<TLDRule> MatchRule(List<TLDRule> rules, string checkAgainst, TLDRule.RuleType ruleType)
    {
        List<TLDRule> matchedResult = new List<TLDRule>();
        foreach (TLDRule rule in rules)
        {
            if (rule.Name.Equals(checkAgainst, StringComparison.InvariantCultureIgnoreCase)
                && rule.Type == ruleType)
            {
                matchedResult.Add(rule);
            }
        }
        return matchedResult;
    }

2 Change this:

        //  Sort our matches list (longest rule wins, according to :
        var results = from match in ruleMatches
                      orderby match.Name.Length descending
                      select match;

        //  Take the top result (our primary match):
        TLDRule primaryMatch = results.Take(1).SingleOrDefault();

into this

        TLDRule primaryMatch = null;
        if (ruleMatches.Count > 0)
        {
            // match2 CompareTo match1 (reverse order) to make the descending
            ruleMatches.Sort(delegate(TLDRule match1, TLDRule match2) { return match2.Name.Length.CompareTo(match1.Name.Length); });
            primaryMatch = ruleMatches[0];
        }

3 change this (TLDRulesCache.cs)

            IEnumerable<TLDRule> lstTLDRules = from ruleString in lstTLDRuleStrings
                                               where
                                               !ruleString.StartsWith("//", StringComparison.InvariantCultureIgnoreCase)
                                               &&
                                               !(ruleString.Trim().Length == 0)
                                               select new TLDRule(ruleString);

into this

List<TLDRule> lstTLDRules = ListTLDRule(lstTLDRuleStrings);

    private static List<TLDRule> ListTLDRule(List<string> lstTLDRuleStrings)
    {
        List<TLDRule> lstTLDRule = new List<TLDRule>();
        foreach (string ruleString in lstTLDRuleStrings)
        {
            if (!ruleString.StartsWith("//", StringComparison.InvariantCultureIgnoreCase)
                &&
                !(ruleString.Trim().Length == 0))
            {
                lstTLDRule.Add(new TLDRule(ruleString));
            }
        }
        return lstTLDRule;
    }

Some others is a small things like:

List<string> lstDomainParts = domainString.Split('.').ToList<string>();

change to:

List<string> lstDomainParts = new List<string>(domainString.Split('.'));

and removing .ToList() like in

"var exceptionresults" will be use exceptionresults.ToList() to get the List. Since "var exceptionresults" change to "List exceptionresults" .ToList() should be removed.

CallMeLaNN

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文