2013-11-01 15 views
10

Dato un URL come segue:Ottenere sottodominio specifico URL in foo.bar.car.com

foo.bar.car.com.au

ho bisogno di estrarre foo.bar.

mi sono imbattuto nel seguente codice:

private static string GetSubDomain(Uri url) 
{ 
    if (url.HostNameType == UriHostNameType.Dns) 
    { 
     string host = url.Host; 
     if (host.Split('.').Length > 2) 
     { 
      int lastIndex = host.LastIndexOf("."); 
      int index = host.LastIndexOf(".", lastIndex - 1); 
      return host.Substring(0, index); 
     } 
    }   
    return null;  
} 

Questo mi dà come foo.bar.car. Voglio foo.bar. Dovrei semplicemente usare split e prendere 0 e 1?

Ma poi è possibile wwww.

C'è un modo semplice per questo?

+0

In primo luogo, manteniamo pulita la lingua. Ma in secondo luogo, dimenticando il codice, come si * sa * che 'foo.bar' è il sottodominio in' foo.bar.car.com.au'? –

+0

mi dispiace per la lingua. Deve essere una cosa americana. Lo so perché lo sto sviluppando. – DarthVader

+0

La domanda non è come tu, @DarthVader, sai. La domanda è, che cosa può assumere il codice? Vedere la mia risposta qui sotto .. –

risposta

10

Dato il vostro requisito (si desidera il 1 ° due livelli, che non includono il 'www.') Mi piacerebbe avvicino qualcosa di simile:

private static string GetSubDomain(Uri url) 
{ 

    if (url.HostNameType == UriHostNameType.Dns) 
    { 

     string host = url.Host; 

     var nodes = host.Split('.'); 
     int startNode = 0; 
     if(nodes[0] == "www") startNode = 1; 

     return string.Format("{0}.{1}", nodes[startNode], nodes[startNode + 1]); 

    } 

    return null; 
} 
1

Si consiglia di utilizzare l'espressione regolare. Il seguente frammento di codice dovrebbe estrarre quello che stai cercando ...

3

OK, primo. Stai guardando in modo specifico in 'com.au' o sono questi nomi di dominio Internet generali? Perché se è quest'ultimo, non c'è semplicemente un modo automatico per determinare quanto del dominio è un "sito" o "zona" o qualsiasi altra cosa e quanto è un singolo "host" o altro record all'interno di quella zona.

Se è necessario essere in grado di capirlo da un nome di dominio arbitrario, si vorrà afferrare l'elenco dei TLD dal progetto Suffisso pubblico Mozilla (http://publicsuffix.org) e utilizzare il loro algoritmo per trovare il TLD nel proprio nome di dominio . Quindi si può presumere che la porzione che si desidera termina con l'ultima etichetta immediatamente prima del TLD.

+0

Questo è molto più corretto della mia risposta da un punto di vista "codice robusto". Se sai che vorresti SEMPRE solo i primi due livelli, il mio funzionerà (come punto di partenza), ma in generale è meglio. – AllenG

2
private static string GetSubDomain(Uri url) 
{ 
    if (url.HostNameType == UriHostNameType.Dns) 
    { 

     string host = url.Host; 
     String[] subDomains = host.Split('.'); 
     return subDomains[0] + "." + subDomains[1]; 
    } 
    return null; 
} 
5

ho affrontato un problema simile e, sulla base di le risposte precedenti, ha scritto questo metodo di estensione. Ancora più importante, ci vuole un parametro che definisce il dominio "root", vale a dire qualsiasi cosa il consumatore del metodo consideri come root. Nel caso del PO, la chiamata sarebbe

Uri uri = "foo.bar.car.com.au"; 
uri.DnsSafeHost.GetSubdomain("car.com.au"); // returns foo.bar 
uri.DnsSafeHost.GetSubdomain(); // returns foo.bar.car 

Ecco il metodo di estensione:

/// <summary>Gets the subdomain portion of a url, given a known "root" domain</summary> 
public static string GetSubdomain(this string url, string domain = null) 
{ 
    var subdomain = url; 
    if(subdomain != null) 
    { 
    if(domain == null) 
    { 
     // Since we were not provided with a known domain, assume that second-to-last period divides the subdomain from the domain. 
     var nodes = url.Split('.'); 
     var lastNodeIndex = nodes.Length - 1; 
     if(lastNodeIndex > 0) 
     domain = nodes[lastNodeIndex-1] + "." + nodes[lastNodeIndex]; 
    } 

    // Verify that what we think is the domain is truly the ending of the hostname... otherwise we're hooped. 
    if (!subdomain.EndsWith(domain)) 
     throw new ArgumentException("Site was not loaded from the expected domain"); 

    // Quash the domain portion, which should leave us with the subdomain and a trailing dot IF there is a subdomain. 
    subdomain = subdomain.Replace(domain, ""); 
    // Check if we have anything left. If we don't, there was no subdomain, the request was directly to the root domain: 
    if (string.IsNullOrWhiteSpace(subdomain)) 
     return null; 

    // Quash any trailing periods 
    subdomain = subdomain.TrimEnd(new[] {'.'}); 
    } 

    return subdomain; 
} 
+0

Se avete intenzione di scrivere un metodo di estensione, perché non estendere 'System.Uri' invece di stringa? Quindi ha un contesto "URL" appropriato. –

+0

@TrueBlueAussie Effettivamente. Ho esteso la stringa semplicemente perché si trattava di un MVP per il mio codebase. Il futuro refactoring porterebbe probabilmente ad estendere System.Uri per mantenere il contesto, come suggerito. – HeyZiko

4

È possibile utilizzare il seguente pacchetto NuGet Nager.PublicSuffix.

PM> Install-Package Nager.PublicSuffix 

Esempio

var domainParser = new DomainParser(); 
var data = await domainParser.LoadDataAsync(); 
var tldRules = domainParser.ParseRules(data); 
domainParser.AddRules(tldRules); 

var domainName = domainParser.Get("sub.test.co.uk"); 
//domainName.Domain = "test"; 
//domainName.Hostname = "sub.test.co.uk"; 
//domainName.RegistrableDomain = "test.co.uk"; 
//domainName.SubDomain = "sub"; 
//domainName.TLD = "co.uk"; 
0

Oltre al pacchetto NuGet Nager.PubilcSuffix specificati in this answer, c'è anche il pacchetto NuGet Louw.PublicSuffix, che secondo il suo GitHub project page è un Core libreria Net che analizza Public Suffix e si basa su Nager.PublicSuffix project, con le seguenti modifiche:

  • Portato a .NET Core Library.
  • Libreria fissa in modo che passi TUTTI i test completi.
  • Classi refactored per suddividere le funzionalità in classi focalizzate più piccole.
  • Classi rese immutabili. Pertanto, DomainParser può essere utilizzato come singleton ed è thread-safe.
  • Aggiunto WebTldRuleProvider e FileTldRuleProvider.
  • Aggiunta funzionalità per sapere se Rule era una regola di dominio privato o ICANN.
  • Usa modello di programmazione asincrona

La pagina afferma anche che molte delle modifiche di cui sopra sono stati sottoposti di nuovo al originale Nager.PublicSuffix project.

Problemi correlati