views:

171

answers:

3

I've recently come to the realization that the .NET apis working with URLs and URIs frequently come up short in achieving even basic functionality (atleast easily) including things such as: generating a FQDN url from a relative path, forcing https or back to http, getting the root of the site, combining relative urls properly and so forth.

Are there any alternative libraries out there that have put all of these type of functionality in a simple and reliable project?

+11  A: 

I've certainly found myself doing much the same URI-manipulation code more than once, in .NET, but I don't see your cases as places it lacks.

Full URI from relative Uri:

new Uri(base, relative) // (works whether relative is a string or a Uri).

Obtaining the actual FQDN:

string host = uri.Host;
string fqdn = hostEndsWith(".") ? host : host + ".";

Forcing https or back to http:

UriBuilder toHttp = new UriBuilder(someUri);
toHttp.Scheme = "http";
toHttp.Port = 80;
return toHttp.Uri;

UriBuilder toHttps = new UriBuilder(someUri);
toHttps.Scheme = "https";
toHttps.Port = 443;
return toHttps.Uri;

Getting the root of the site:

new Uri(startingUri, "/");

Combining relative urls properly:

new Uri(baseUri, relUri); // We had this one already.

Only two of these are more than a single method call, and of those obtaining the FQDN is pretty obscure (unless rather than wanting the dot-ended FQDN you just wanted the absolute URI, in which case we're back to a single method call).

There is a single method version of the HTTPS/HTTP switching, though it's actually more cumbersome since it calls several properties of the Uri object. I can live with it taking a few lines to do this switch.

Still, to provide a new API one need only supply:

public static Uri SetHttpPrivacy(this Uri uri, bool privacy)
{
    UriBuilder ub = new UriBuilder(uri);
    if(privacy)
    {
        ub.Scheme = "https";
        ub.Port = 443;
    }
    else
    {
        ub.Scheme = "http";
        ub.Port = 80;
    }
    return ub.Uri;
}

I really can't see how an API could possibly be any more concise in the other cases.

Jon Hanna
+1 for http vs. https, don't forget to set the port on UriBuilder, it'll keep the wrong port otherwise i.e. 443 instead of 80 for http.
eglasius
@eglasius right you are, I've editted. Of course, strictly the original was the one that did things to the requirement (you can after all offer HTTPS on port 80 and HTTP on port 443 if you want), but what I now have does what would generally be wanted.
Jon Hanna
You made a copy/paste mistake, you assign the port 443 to `scheme`.
Daniel Beck
@Daniel. LOL, the problem was because I didn't copy-paste. It was also the wrong casing. Thanks.
Jon Hanna
+1 from me, point well made!
Rob
Jon Hanna
+2  A: 

I use a combination of extensions with 'System.IO.Path' object as well.

These are just blurbs for example.

 public static Uri SecureIfRemote(this Uri uri){



if(!System.Web.HttpContext.Current.Request.IsSecureConnection &&
                !System.Web.HttpContext.Current.Request.IsLocal){
return new Uri......(build secure uri here)
}

return uri;

    }

public static NameValueCollection ParseQueryString(Uri uri){
return uri.Query.ParseQueryString();
}


    public static NameValueCollection ParseQueryString(this string s)
    {
        //return
        return HttpUtility.ParseQueryString(s);
    }
BlackjacketMack
+3  A: 

XUri is a nice class that is part of the open source project from MindTouch

http://developer.mindtouch.com/en/ref/dream/MindTouch.Dream/XUri?highlight=XUri

This article includes a quick sample on how to use it.

http://blog.developer.mindtouch.com/2009/05/18/consuming-rest-services-and-tdd-with-plug/

I am a fan of it. A little overkill assembly wise if you are going to just use the XUri portion, but there are other really nice things in the library too.

Foovanadil
This looks like it has alot of potential, I figured there had to be a library similar to this.
Chris Marisic
Sigh once again SO eats my bounty. Sorry I couldn't assign it to you. I don't understand why they auto assign it immediately, why not wait a few days after the time period (or in this case a few hours) for the user to be able to assign it after the full 7 days instead of having to cut it short.
Chris Marisic
No sweat. Glad you find it useful.
Foovanadil