2015-02-03 7 views
1

저는 오늘 C# 토지에 있습니다. 사용자 에이전트 문자열을 받아들이고 적어도 브라우저 이름과 버전을 제공하는 객체를 반환하는 함수를 작성하려고합니다. 그래서 this answer을 시도했지만 AppleMAC-Safari 5.0으로 Chrome을보고합니다. 가장 인기있는 브라우저를 잘못보고하는 것은 실제로 용납되지 않습니다.C# .Net에서 browscap.ini 또는 xml 사용

browscap.ini 또는 XML 또는 JSON에 액세스 할 수 있습니다. 그것은 수동으로 할 필요가있는 것처럼 보이지만 그 파일의 정규식은 C#에서 정규 표현식과 호환되지 않습니다. 이것은 일종의 악몽입니다.

Visual Studio 및 .Net 3.5를 사용하고 있습니다.

+1

사용자 에이전트 문자열 Chrome 40.0.2214.94 m은 Mozilla/5.0 (Windows NT 6.1, WOW64) AppleWebKit/537.36 (Gecko와 같은 KHTML) Chrome/40.0.2214.94 Safari/537.36'입니다. Chrome/이 포함되어 있으므로 Regex를 사용할 수 있습니다. 지원하려는 다른 브라우저의 사용자 에이전트 문자열을 검사하고 유사한 작업을 수행하십시오. 사용자가 어떤 브라우저를 사용하고 있는지를 감지하는 데 업무 적으로 중요한 것이 있습니까? – adamdc78

+0

@ adamdc78 비즈니스 크리티컬하다고 말하지 않습니다. 나는 단순히 어떤 브라우저 사용자가 로그인했는지 기록하고있다. 몇 분 안에 PHP로 작업 할 수 있지만 C#에서는 불가능한 것 같습니다. 이 시점에서 C#을 사용하여 간단한 PHP 스크립트를 호출하는 것이 더 쉬울 수도 있습니다 ... – Andrew

답변

1

이 질문에 정말 기쁩니다. 그것은 나를 영원히 괴롭 히고있다. 기본적으로 할 일은 browscap 파일 중 하나를 가져 와서 파싱하는 것입니다. 나는 XML 파일을 사용했다. 거기에서 사용자 에이전트 문자열에 대해 각 정규식 패턴을 확인해야합니다. XML 파일에서 각 browscapitem의 "name"속성입니다.

그러나 파일의 패턴을 실제 정규 표현식으로 변환해야 C#이이를 인식 할 수 있습니다. 이것은 귀하의 문제에 필요한 주요 방법입니다. 다른 모든 것은 다른 파일 형식을 구문 분석하는 것일뿐입니다.

는 (나는 다른 사람들이이 PHP에서 작동하도록 한 일을보고 this code을 사용했다.)

public static Boolean BrowserPatternMatches(string pattern, string input) 
{ 
    string patternConverted = "^" + pattern 
       .Replace("\\", "\\\\") 
       .Replace(".", "\\.") 
       .Replace("?", ".") 
       .Replace("*", ".*") 
       .Replace("$", "\\$") 
       .Replace("[", "\\[") 
       .Replace("]", "\\]") 
       .Replace("|", "\\|") 
       .Replace("(", "\\(") 
       .Replace(")", "\\)") 
       .Replace("+", "\\+") 
       .Replace("{", "\\{") 
       .Replace("}", "\\}") 
       .Replace("%", "\\%") 
       + "$"; 
    Regex regex = new Regex(patternConverted); 
    return regex.IsMatch(input); 
} 

이 문제의 고기입니다. 나머지는 XML을 파싱하고 그 값을 얻는 문제입니다. 이것은 나의 전문 지식 영역이 아니므로, 나는 그 기능을 충분히 발휘할 수있었습니다. 수업 시간에 나는 다음과 같은 것을 가지고 있습니다 :

private Dictionary<string, Dictionary<string, string>> dic = new Dictionary<string, Dictionary<string, string>>(); 

private void FillDictionary() 
{ 
    if (this.dic.Count == 0) 
    { 
     XmlTextReader reader = new XmlTextReader("browscap.xml"); 

     while (reader.Read()) 
     { 
      if (reader.Name == "browscapitem") 
      { 
       string pattern = reader.GetAttribute("name"); 
       if (pattern != null) 
       { 
        if (!this.dic.ContainsKey(pattern)) 
        { 
         Dictionary<string, string> properties = new Dictionary<string, string>(); 
         while (reader.Read()) 
         { 
          if (reader.Name == "browscapitem") 
          { 
           break; 
          } 
          if (reader.GetAttribute("name") != null) 
          { 
           properties.Add(reader.GetAttribute("name").ToLower(), reader.GetAttribute("value")); 
          } 
         } 
         this.dic.Add(pattern, properties); 
        } 
       } 
      } 
     } 
    } 
} 

나머지는 "부모"속성을 채우기위한 몇 가지 속임수입니다. 당신이 당신의 이상형을 찾을 번 그래서, 당신은 돌아가서 등 부모 및 부모의 부모를 찾을 수있다

여기
private Dictionary<string, string> GetBrowserProps(string parentId) 
{ 
    return this.dic[parentId]; 
} 

public Dictionary<string, string> GetBrowserObject(string uaString) 
{ 
    this.FillDictionary(); 

    bool found = false; 
    string foundKey = ""; 

    foreach (string pattern in this.dic.Keys) 
    { 
     if (!found) 
     { 
      found = RecordBrowsers.BrowserPatternMatches(pattern, uaString); 
      if (found) { foundKey = pattern; break; } 
     } 
    } 

    Dictionary<string, string> browserProps = new Dictionary<string, string>(); 
    if (foundKey != "") 
    { 
     browserProps = this.GetBrowserProps(foundKey); 
     Dictionary<string, string> current = this.GetBrowserProps(foundKey); 
     bool cont = current.ContainsKey("parent"); 
     while (cont) 
     { 
      Dictionary<string, string> parent = this.GetBrowserProps(current["parent"]); 
      foreach (string s in parent.Keys) 
      { 
       if (!browserProps.ContainsKey(s)) 
       { 
        browserProps.Add(s, parent[s]); 
       } 
      } 
      current = parent; 
      cont = current.ContainsKey("parent"); 
     } 
    } 

    return browserProps; 
} 

좋은 측정을위한 내 시험이다 : 대한

Console.WriteLine("RecordBrowser started"); 

string[] strs = { "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.94 Safari/537.36", 
        "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:35.0) Gecko/20100101 Firefox/35.0", 
        "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.94 Safari/537.36 OPR/27.0.1689.66", 
        "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.94 Safari/537.36", 
        "Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.8.1.8pre) Gecko/20070928 Firefox/2.0.0.7 Navigator/9.0RC1", 
        "Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/20121202 Firefox/17.0 Iceweasel/17.0.1"}; 

string[] expectedResults = { "Chrome 40.0", "Firefox 35.0", "Opera 27.0", "Chrome 40.0", "Netscape 9.0", "Iceweasel 17.0" }; 

for(int i=0; i<strs.Length; i++) 
{ 
    Dictionary<string, string> browserProps = this.GetBrowserObject(strs[i]); 
    if (browserProps["comment"] == expectedResults[i]) 
    { 
     Console.WriteLine("test " + i + " passed"); 
    } 
    else 
    { 
     Console.WriteLine("test " + i + " failed"); 
    } 
    Console.WriteLine("**********************************************************"); 
} 
Console.WriteLine("DONE");