Quick question:
Can anyone think of a better way then RegEx or general text searching to work out whether a Uri object (not URL string) has a file extension?
Any thoughts welcome. Apologies if I've missed something in the .NET framework / Uri class that already does this.
Slightly more complexity wise.
I've accepted craigtp's answer; however, for what I need the solution is thus.
var hasExtension = Path.HasExtension(requestUri.AbsolutePath);
To all who had a go at this. For a full and comprehensive answer, you would obviously need a mime types dictionary to do a further check. For example http://example/this.is.sort.of.valid.but.not.a.mime.type would return "true" has Path.HasExtension
, however, for what I need, I would never have this type of path coming in.
You can use the HasExtension
method of the System.IO.Path
class to determine if a Uri's string has an extension.
By using the AbsoluteUri
property of the Uri
object, you can retrieve the complete string that represents the Uri. Passing this string to the Path class's HasExtension
method will correctly return a boolean indicating whether the Uri contains a file extension.
Copy and paste the following code into a simple console application to test this out. Only myUri3
and myUrl4
return True, which also demonstrates that the HasExtension
method can correctly deal with additional characters (i.e. Querystrings) after the filename (and extension).
using System; using System.IO; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { Uri myURI1 = new Uri(@"http://www.somesite.com/"); Uri myURI2 = new Uri(@"http://www.somesite.com/filenoext"); Uri myURI3 = new Uri(@"http://www.somesite.com/filewithext.jpg"); Uri myURI4 = new Uri(@"http://www.somesite.com/filewithext.jpg?q=randomquerystring"); Console.WriteLine("Does myURI1 have an extension: " + Path.HasExtension(myURI1.AbsoluteUri)); Console.WriteLine("Does myURI2 have an extension: " + Path.HasExtension(myURI2.AbsoluteUri)); Console.WriteLine("Does myURI3 have an extension: " + Path.HasExtension(myURI3.AbsoluteUri)); Console.WriteLine("Does myURI4 have an extension: " + Path.HasExtension(myURI4.AbsoluteUri)); Console.ReadLine(); } } }
EDIT:
Based upon the question asker's edit regarding determining if the extension is a valid extension, I've whipped up some new code below (copy & paste into a console app):
using System; using System.IO; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { Uri myUri1 = new Uri("http://www.somesite.com/folder/file.jpg?q=randomquery.string"); string path1 = String.Format("{0}{1}{2}{3}", myUri1.Scheme, Uri.SchemeDelimiter, myUri1.Authority, myUri1.AbsolutePath); string extension1 = Path.GetExtension(path1); Console.WriteLine("Extension of myUri1: " + extension1); Uri myUri2 = new Uri("http://www.somesite.com/folder/?q=randomquerystring"); string path2 = String.Format("{0}{1}{2}{3}", myUri2.Scheme, Uri.SchemeDelimiter, myUri2.Authority, myUri2.AbsolutePath); string extension2 = Path.GetExtension(path2); Console.WriteLine("Extension of myUri1: " + extension2); Console.ReadLine(); } } }
This new code now de-constructs all of the component parts of a Uri object (i.e. Scheme - the http
part etc.) and specifically removes any querystring part of the Uri. This gets around the potential problem as noted by Adriano in a comment on this answer that the querystring could contain a dot character (thereby potentially messing up the HasExtension
method).
Once the Uri is de-constructed, we can now properly determine both if the Uri string has an extension and also what that extension is.
From here, it's merely a case of matching this extension against a list of known valid extensions. This part is something that the .NET framework will never given you as any file extension is potentially valid (any application can make up it's own file extension if it so desires!)
The Uri.IsFile property suggested by others does not work.
From the docs
The IsFile property is true when the Scheme property equals UriSchemeFile. file://server/filename.ext"
http://msdn.microsoft.com/en-us/library/system.uri.isfile.aspx
What you can do is get the AbsolutePath of the URI (which corresponds to /contact or /images/logo.png for example) and then use the FileInfo class to check/get the extension.
var uris = new List<Uri>() { new Uri("http://mysite.com/contact"), new Uri("http://mysite.com/images/logo.png"), new Uri("http://mysite.com/images/logo.png?query=value"), }; foreach (var u in uris) { var fi = new FileInfo(u.AbsolutePath); var ext = fi.Extension; if (!string.IsNullOrWhiteSpace(ext)) { Console.WriteLine(ext); } }
You probably need to check against a list of supported extensions to handle the more complicated cases (contact.is.sortof.valid and contact.is.sortof.valid.png)
Tests:
"http://mysite.com/contact" //no ext "http://mysite.com/contact?query=value" //no ext "http://mysite.com/contact?query=value.value" //no ext "http://mysite.com/contact/" //no ext "http://mysite.com/images/logo.png" //.png "http://mysite.com/images/logo.png?query=value" //.png "http://mysite.com/images/logo.png?query=value.value" //.png "http://mysite.com/contact.is.sortof.valid" //.valid "http://mysite:123/contact.is.sortof.valid" //.valid
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With