2

この回答Get the subdomain from a URLに基づいて、私は code.google.com/p/domainname-parser/ を使用しようとしています。これは publicsuffix.org からパブリック サフィックス リストを使用して、Cookie コレクションを管理するためのサブドメインとドメインを取得します。

現時点では、Domainname-parser は publicsuffix.org のリストを実装するインターネットで見つけた唯一の .NET コードです。

Domainname-parser を使用するために、次のことができるようにソース コードを変更したいと考えています。

  1. .NET 2.0 での使用
  2. Uri オブジェクトを受け入れて、ホストをサブドメイン、ドメイン、および TLD に解析します。
  3. LastModified が変更された場合、WebRequest と WebResponse を使用して、publicsuffix.org から最新のリストを自動的にダウンロードします。

そのため、より使いやすくなり、常に更新されます。(2) と (3) は問題ありませんが、(1) が今の私の焦点です。

現在のドメイン名パーサーは v1.0 で、コードで Linq を使用する .NET 3.5 を使用するようにビルドされています。.NET 2.0 と互換性を持たせるには、Linq コードを非 Linq に変換する必要があります。これにより、Public Suffix List のルールを理解することができます。それが通常、ワイルドカード、および例外ルールです。ただし、Linq と、それを通常の方法に戻す方法についての知識はありません。

コンバーター ツールは便利かもしれませんが、1 行ずつ確認して変更する方が良いでしょう。

今私の質問は、どうすればそれを変換できますか? たとえば、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;

従うべき簡単なガイドラインは何ですか? または、上記の 1 つの文を .NET 2.0 の通常の C# コードに変換する無料のツールはありますか?

コレクションを扱う方法だけで、データベースは関係ないと思います。

また、ドメイン名パーサーの所有者に連絡してコードを改善し、これを解決する手助けをしようとしています。

ありがとう

CallMeLaNN

4

2 に答える 2

1

本当に助けてくれたJonSkeetに感謝します。それは非常にうまく機能し、すべてのUnitTestは正常に合格しました。

ここでは、.NET2.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;
    }

他のいくつかは次のような小さなものです:

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

への変更:

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

のように.ToList()を削除します

「varexceptionresults」は、exceptionresults.ToList()を使用してリストを取得します。「varexceptionresults」が「Listexceptionresults」に変更されたため、.ToList()を削除する必要があります。

CallMeLaNN

于 2009-10-09T09:45:40.510 に答える
1

さて、コメントに応えて、リストを返すバージョンを次に示します。

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# の詳細) を持っている場合は、第 8 章から第 11 章で LINQ to Objects について知る必要があるすべてのことを説明します。

VS2008 を使用できるが、 .NET 2.0のみをターゲットとする場合の別の代替手段は、LINQ to Objects for .NET 2.0 の再実装であるLINQBridgeを使用することです...そして現在はオープンソースです:)

于 2009-10-09T07:03:21.837 に答える