Budowanie i parsowanie adresów URL w .NET

Tworzenie i parsowanie adresów URL wykorzystując narzędzia dostarczone przez platformę .NET.

Traktowanie adresu URL jako stringa w programach jest dość wygodne jeżeli służy on tylko do przechowania adresu danego zasobu sieciowego. Jeżeli jednak takie adresy musimy generować lub wyciągać z nich niektóre parametry używanie stringa staje się nie praktyczne i wymusza na nas pisanie dodatkowych narzędzi. Wszystko w tym było by ok jeżeli pominąć fakt że framework .NET dostarcza nam właśnie zestaw klas do całej gamy operacji na adresach sieciowych.

Relacje między URI, a URL i URN.

Główną klasą odpowiedzialną za przechowywania adresów sieciowych jest klasa Uri. Jak widać nazwa klasy wskazuje, że posługujemy się URI (Uniform Resource Identifier), czyli czymś nadrzędnym niż sam URL.

Zatem platforma .NET dostarcza nam narzędzie o szerszym zastosowaniu niż budowanie samych adresów URL. Aby móc korzystać z klasy Uri jak i innych wymienionych w tym wpisie musimy do naszego projektu dodać referencję do System.ServiceModel.

Dzięki klasie Uri oprócz przechowywania danego identyfikatora sieciowego mamy możliwość weryfikacji jego poprawności przy tworzeniu takiego obiektu, jak również dostęp do poszczególnych jego części. Za pomocą tej klasy możemy tworzyć zarówno adresy względne (relative) jak i bezwzględne (absolute).

[csharp autolinks=”false”]Uri relative = new Uri("/2010/08/12/budowanie-i-parsowanie-adresow-url-w-net", UriKind.Relative);

Uri absolute = new Uri("http://blog.pietowski.com/2010/08/12/budowanie-i-parsowanie-adresow-url-w-net", UriKind.Absolute);
[/csharp]

Warto zapamiętać fakt, że obiektów klasy Uri nie można modyfikować gdyż wszystkie właściowści tej klasy umożliwiają tylko pobranie danych. Jeżeli chcemy mieć możliwość modyfikacji obiektu po jego utworzeniu powinniśmy użyć do tego celu klasy UriBuilder.

[csharp]
UriBuilder blogUri = new UriBuilder();
blogUri.Scheme = Uri.UriSchemeHttp;
blogUri.Host = "blog.pietowski.com";
blogUri.Query = "file_id=2&lang=pl";

Console.WriteLine(blogUri.Uri);
[/csharp]

Jednak najbardziej przydatną i użyteczną klasą wydaje się być UriTemplate gdyż umożliwia nam definiowanie szablonów naszego identyfikatora sieciowego. Dzięki czemu możemy np. tworzyć automatycznie wiele adresów URL z różnymi parametrami jak również pobierać wybrane parametry z gotowych już adresów.

Elementem niezbędnym do utworzenia obiektu klasy UriTemplate jest string zawierający szablon tworzonych URI, który przekazujemy do konstruktora tej klasy. Format takiego stringa może mieć różne postacie, na przykład:

  • /2010/08/12/budowanie-i-parsowanie-adresow-url-w-net
  • /2010/{mounth}/{day}/{title}
  • /{year}/*?file_id={id}
  • /{year}/{mounth}/{day}/{title}?file_id={id}
  • /{year}/{mounth}/{day}/{title}?file_id=2

Przy tworzeniu obiektu weryfikowana jest poprawność wprowadzonego formatu zatem nie musimy się martwić, że przez przypadek wprowadzimy błędne dane. Nazwy zmiennych zamiast których będą wstawiane odpowiednie wartości zapisujemy między nawiasami klamrowymi “{” “}”. Wstawienie odpowiednich wartości do adresu uzyskujemy przy pomocy metody BindByPosition(Uri, String[]) do której przekazujemy bazowy adres i wszystkie parametry w kolejności w jakiej występują w szablonie.

[csharp autolinks=”false”]UriTemplate template = new UriTemplate("/{year}/{mounth}/{day}/{title}");
Uri baseAddress = new Uri("http://blog.pietowski.com");
Uri positionalUri = template.BindByPosition(baseAddress, "2010", "08", "12","budowanie-i-parsowanie-adresow-url-w-net");
[/csharp]

Innym sposobem przekazania parametrów jest  utworzenie kolekcji NameValueCollection. Do obiektu takiej kolekcji dodajemy pary: nazwę parametru i jego wartość. Wynikowy Uri uzyskujemy wykonując metodę BindByName(Uri, NameValueCollection)do której przekazujemy bazowy adres i stworzoną kolekcję parametrów, co obrazuje poniższy przykład.

[csharp autolinks=”false”]UriTemplate template = new UriTemplate("/{year}/{mounth}/{day}/{title}");
Uri baseAddress = new Uri("http://blog.pietowski.com");

NameValueCollection parameters = new NameValueCollection();
parameters.Add("year", "2010");
parameters.Add("mounth", "08");
parameters.Add("day", "12");
parameters.Add("title", "budowanie-i-parsowanie-adresow-url-w-net");

Uri namedUri = template.BindByName(baseAddress, parameters);
[/csharp]

Szczególne znaczenie w szablonie identyfikatora URI ma gwiazdka “*”, która służy do zastępowania pozostałej część ścieżki adresu.  Symbol gwiazdki musi wystąpić raz  i musi znajdować się na końcu ścieżki tworzonego szablonu URI. Stosowanie takiego zapisu przydaje się najbardziej w czasie dopasowywania gotowych Uri do stworzonego szablonu, służy do tego metoda Match(Uri, Uri). Metoda ta zwraca obiekt klasy UriTemplateMatch, z którego możemy pobierać poszczególne parametry szablonu ze wskazanego obiektu klasy Uri. Jeżeli wskazany Uri nie pasuje do szablonu zostanie zwrócony null.

Właściwość WildcardPathSegments w klasie UriTemplateMatch umożliwia pobranie segmentów pozostałej ścieżki, którą w szablonie zastąpiliśmy “*”:

[csharp autolinks=”false”]UriTemplate template = new UriTemplate("/{year}/*?file_id={id}");
Uri baseAddress = new Uri("http://blog.pietowski.com");
Uri fullUri = new Uri("http://blog.pietowski.com/2010/08/12/budowanie-i-parsowanie-adresow-url-w-net?file_id=2");

// Match a URI to a template
UriTemplateMatch results = template.Match(baseAddress, fullUri);
if (results != null)
{
Console.WriteLine("WildcardPathSegments:");
foreach (string segment in results.WildcardPathSegments)
{
Console.WriteLine("{0}", segment);
}
}
[/csharp]

Powyższy kod zwróci nam następujący wynik:

WildcardPathSegments:
08
12
budowanie-i-parsowanie-adresow-url-w-net

Klasa UriTemplateMatch posiada poza wspomnianą powyżej wiele różnych właściwości dzięki którym możemy pobierać poszczególne elementy ścieżki, nazwy i wartości parametrów jak i wiele innych. Poniższy przykład prezentuję zastosowanie kilku z nich:

[csharp autolinks=”false”]
UriTemplate template = new UriTemplate("/{year}/{mounth}/{day}/{title}?file_id={id}&lang={lang}");
Uri baseAddress = new Uri("http://blog.pietowski.com");
Uri fullUri = new Uri("http://blog.pietowski.com/2010/08/12/budowanie-i-parsowanie-adresow-url-w-net?file_id=2&lang=pl");

UriTemplateMatch results = template.Match(baseAddress, fullUri);
if (results != null)
{
Console.WriteLine("BoundVariables:");
foreach (string variableName in results.BoundVariables.Keys)
{
Console.WriteLine("{0}: {1}",
variableName, results.BoundVariables[variableName]);
}
Console.WriteLine();

Console.WriteLine("QueryParameters:");
foreach (string queryName in results.QueryParameters.Keys)
{
Console.WriteLine("{0} : {1}",
queryName, results.QueryParameters[queryName]);
}
Console.WriteLine();

Console.WriteLine("RelativePathSegments:");
foreach (string segment in results.RelativePathSegments)
{
Console.WriteLine("{0}", segment);
}
}
[/csharp]

Po wykonaniu takiego kodu ujżymy w konsoli następujący wynik.

BoundVariables:
YEAR: 2010
MOUNTH: 08
DAY: 12
TITLE: budowanie-i-parsowanie-adresow-url-w-net
ID: 2
LANG: pl

QueryParameters:
file_id : 2
lang : pl

RelativePathSegments:
2010
08
12
budowanie-i-parsowanie-adresow-url-w-net

Teraz przed pisaniem wyrażeń regularnych czy budowaniem własnych parserów warto przemyśleć zastosowanie gotowego rozwiązania jakie dostarcza nam platforma .NET gdyż w większości przypadków może to być najlepsze wyjście, które znacznie ułatwi nam posługiwanie się adresami sieciowymi w naszej aplikacji.

Więcej informacji odnoście opisywanych klas można znaleźć na stronach MSDN.

426 thoughts on “Budowanie i parsowanie adresów URL w .NET”

  1. Good post. I study one thing more difficult on different blogs everyday. It’s going to at all times be stimulating to read content from different writers and practice a little bit something from their store. I抎 favor to use some with the content material on my weblog whether you don抰 mind. Natually I抣l offer you a hyperlink on your web blog. Thanks for sharing.

  2. Hi there this is somewhat of off topic but I was wondering if blogs use WYSIWYG
    editors or if you have to manually code with HTML. I’m
    starting a blog soon but have no coding skills so I wanted to get advice from someone with experience.
    Any help would be enormously appreciated!

  3. After research just a few of the blog posts on your web site now, and I really like your means of blogging. I bookmarked it to my bookmark website checklist and might be checking back soon. Pls try my website as effectively and let me know what you think.

  4. Dating when your over 30 can seem tough. We all had plans to be married by 26 right? Well, thanks to 30 Plus Dating, 30 is the new 20! So make this new years start with a bang

  5. I simply couldn’t leave your website prior to suggesting that
    I extremely loved the standard info an individual supply for your visitors?
    Is gonna be again ceaselessly in order to check out new posts

  6. I and also my pals appeared to be checking out the good tricks on your site while quickly got an awful feeling I never thanked the web site owner for those tips. These young boys are already as a result warmed to see them and have in effect definitely been having fun with those things. I appreciate you for really being so considerate and for using these kinds of beneficial resources millions of individuals are really desperate to understand about. My very own sincere apologies for not expressing appreciation to earlier.

  7. I was more than happy to uncover this great site.
    I wanted to thank you for your time due to this wonderful read!!
    I definitely liked every part of it and I have you book-marked to check out new stuff in your blog.

  8. I do trust all the concepts you’ve introduced for your post.

    They’re very convincing and will certainly work.

    Nonetheless, the posts are very quick for newbies. Could you please extend them a bit from next time?
    Thanks for the post.

  9. Howdy I am so excited I found your blog page, I really found you by mistake,
    while I was browsing on Aol for something else, Nonetheless I
    am here now and would just like to say cheers for a incredible post and
    a all round thrilling blog (I also love the theme/design), I
    don’t have time to read it all at the moment but I have saved it and also added your RSS feeds, so when I have
    time I will be back to read a great deal more, Please do keep up the superb b.

  10. I want to convey my gratitude for your kind-heartedness supporting persons that have the need for help on the matter. Your special commitment to passing the message throughout turned out to be quite important and have always enabled folks much like me to attain their pursuits. Your entire warm and friendly help and advice implies a great deal a person like me and additionally to my office workers. With thanks; from everyone of us.

  11. Its such as you learn my thoughts! You appear to grasp so much approximately this,
    such as you wrote the book in it or something. I think that you can do with a few percent to force the message home
    a little bit, but instead of that, that is fantastic blog.
    A fantastic read. I will definitely be back.

  12. What’s up mates, how is all, and what you desire to
    say on the topic of this paragraph, in my view its truly amazing in favor of me.

  13. naturally like your web-site but you need to take a look at the spelling on several of your posts.

    Several of them are rife with spelling problems and I find it very troublesome to tell the reality nevertheless I will definitely come
    again again.

  14. A fascinating discussion is worth comment. I think that you ought to
    write more about this issue, it may not be a taboo matter but generally folks don’t talk about these topics.
    To the next! Cheers!!

  15. Hi! I simply would like to give you a huge thumbs up for the great info you have
    right here on this post. I will be returning
    to your blog for more soon.

  16. Pretty section of content. I just stumbled upon your site and in accession capital to assert that I get in fact enjoyed
    account your blog posts. Anyway I will be subscribing
    to your augment and even I achievement you access consistently quickly.

  17. The following time I learn a blog, I hope that it doesnt disappoint me as much as this one. I mean, I know it was my choice to learn, but I truly thought youd have something interesting to say. All I hear is a bunch of whining about one thing that you might repair should you werent too busy on the lookout for attention.

  18. You really make it seem so easy with your presentation but
    I find this topic to be actually something which I think I would never understand.
    It seems too complicated and very broad for me. I’m looking
    forward for your next post, I will try to get the hang of it!

  19. I don’t have any idea how I ended up being here, but
    I thought this post was great. I do not know who you are but definitely you’re going to
    a well known blogger in case you aren’t already All the best!

  20. My wife and i felt absolutely more than happy Emmanuel could complete his reports through the entire precious recommendations he acquired out of the site. It’s not at all simplistic to simply be freely giving helpful tips which the others have been making money from. And now we figure out we need the website owner to appreciate for that. These explanations you have made, the simple site navigation, the relationships you can assist to create – it is mostly sensational, and it is helping our son and the family reason why the concept is cool, and that’s truly fundamental. Thank you for the whole thing!

  21. This is actually interesting, you are a really professional blogger.

    I’ve joined your rss feed as well as sit up for
    searching for more of your great post.In addition, I have shared your site in my
    social networks!

  22. Thanks for your marvelous posting! I definitely enjoyed reading it, you’re a great author.I will be sure to bookmark your
    blog and may come back down the road. I want to encourage one to continue your great posts, have a nice holiday weekend!

  23. Sweet blog! I found it while browsing on Yahoo News. Do you have any tips on how to get listed in Yahoo News? I’ve been trying for a while but I never seem to get there! Thank you

  24. Youre so cool! I dont suppose Ive learn something like this before. So good to find somebody with some unique thoughts on this subject. realy thank you for beginning this up. this website is one thing that’s wanted on the net, somebody with a little originality. useful job for bringing one thing new to the web!

  25. excellent submit, very informative. I wonder why the other experts of this sector don’t realize this.
    You must proceed your writing. I’m confident, you have a huge readers’ base already!

  26. This is my first time i visit here. I found so many helpful stuff in your website especially its discussion. From the tons of responses on your posts, I guess I am not the only one having all the enjoyment here! keep up the excellent work

Leave a Reply