Convert Linq to normal C # .NET 2.0 for parser domain name codes that use publicsuffix.org

Based on this answer Get subdomain from url , I am trying to use code.google.com/p/domainname-parser/, which will use Public Suffix List from publicsuffix.org to get subdomain and domain to manage my cookie collection.

Domainname-parser is currently the only .NET code I have found on the Internet that implements the list from publicsuffix.org.

To use Domainname-parser, I want to modify my source code so that it can:

  • Use in .NET 2.0
  • Accept Uri object to parse node into subdomain, domain and TLD.
  • The latest list from publicsuffix.org will be automatically loaded using WebRequest and WebResponse if LastModified is changed.

Thus, it will become more useful and will always be updated. (2) and (3) wouldn't be a problem, but (1) is my focus now.

Current Domainname-parser is v1.0, build for using .NET 3.5 which uses Linq in the code. To make it compliant with .NET 2.0, I need to convert my Linq codes to non-Linq, and that makes me understand the Public Suffix List rules. These are Normal, Wildcard and Exception rules. However, I am not aware of Linq and how it can be converted back to normal mode.

The converter tools can be helpful, but the better I go through and change it line by line.

Now my question is, how can I convert it? For example, codes from the FindMatchingTL; DRule method in the 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's a simple guide line? or any free tools to convert this suggestion above to regular C # codes in .NET 2.0.?

I believe no database had anything to do with how they work with collections.

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

thank

CallMeLaNN

+2


source to share


2 answers


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

Here I want to share with you someone who wants to use Domainname-parser in .NET 2.0

1 Change these 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;

      

in it:

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

      

in that

        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 (TL; DRulesCache.cs)



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

      

in that

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 are little things like:

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

      

change to:

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

      

and removing .ToList () as in

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

CallMeLaNN

+1


source


Ok, in response to comments, here's a version that returns 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 are converting a lot of code (and if you really need to convert it - see below), you should really learn more about LINQ. Eventually you will end up using it, and if you understand how it works, you will be in a much better position to decide how to make the conversion. The most recent C # books cover LINQ; if you have your own book (C # in Depth) then Chapters 8-11 will cover everything you need to know for LINQ to Objects.

Another alternative, if you can use VS2008, but only target .NET 2.0 is to use LINQBridge , which is a re-implementation of LINQ to Objects for .NET 2.0 ... and now open source :)

+1


source







All Articles