5

I want to validate a file uploader, by file extension. If the file extension is not equal to .jpg, .jpeg, .gif, .png, .bmp then throw validation error.

Is there a way to do this without looping through each type?

abatishchev
  • 98,240
  • 88
  • 296
  • 433
Chaddeus
  • 13,134
  • 29
  • 104
  • 162

8 Answers8

28

Just build a collection - if it's small, just about any collection will do:

// Build the collection once (you may want a static readonly variable, for
// example).
List<string> list = new List<string> { ".jpg", ".jpeg", ".gif", ".bmp", ... };

// Later
if (list.Contains(extension))
{
    ...
}

That does loop over all the values of course - but for small collections, that shouldn't be too expensive. For a large collection of strings you'd want to use something like HashSet<string> instead, which would provide a more efficient lookup.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
5

You can use !Regex.IsMatch(extension, "^\.(jpg|jpeg|gif|png|bmp)$")

but internally somehow it will still loop

fixagon
  • 5,506
  • 22
  • 26
  • 1
    That highlights the downside of using a regex - the "." there doesn't mean period, it means any character... probably not what you meant... – Jon Skeet Oct 10 '11 at 08:54
  • @fantasticfix: But my point is that it's easy to make that sort of mistake with regular expressions, and you're not really using the "pattern" nature of regexes... so why use them at all? It's much simpler to avoid all the escaping worries etc by just using a collection. – Jon Skeet Oct 10 '11 at 08:57
  • 1
    i agree partly. but case-related matters would be more easy to handle in regex imho. depends what you are more comfortable with. – fixagon Oct 10 '11 at 09:04
3

Stick the extensions in a collection, then check if the extension of your file is in that collection.

Svish
  • 152,914
  • 173
  • 462
  • 620
3

It will require a loop, but you can do this with LINQ (hides the loop)

ie:

using System.Linq;

private readonly string[] _matches = new[] { ".jpg", ".bmp", ".png", ".gif", ".bmp" };    

// Assumes extension is in the format ".jpg", "bmp", so trim the
// whitespace from start and end
public bool IsMatch(string extension)
{
     return _matches.Contains(extension);
}

It could also be done with Regex but I'm no regex wizz so I'll leave that to another poster :)

Dr. Andrew Burnett-Thompson
  • 20,980
  • 8
  • 88
  • 178
2

Use the following 2 extensions. I wrote about them in an article on CodeProject. Here you go: http://www.codeproject.com/KB/dotnet/MBGExtensionsLibrary.aspx

        public static bool In<T>(this T t, IEnumerable<T> enumerable)
        {
            foreach (T item in enumerable)
            {
                if (item.Equals(t))
                { return true; }
            }
            return false;
        }

        public static bool In<T>(this T t, params T[] items)
        {
            foreach (T item in items)
            {
                if (item.Equals(t))
                { return true; }
            }
            return false;
        }

Of course it still requires a loop, but the good thing is you don't have to do that work. It also means you don't have to write code like this:

if (myString == "val1" ||
   myString == "val2" ||
   myString == "val3" ||
   myString == "val4" ||
   myString == "val5")
   {
      //Do something
   }
Svish
  • 152,914
  • 173
  • 462
  • 620
Matt
  • 6,787
  • 11
  • 65
  • 112
1

There's an answer to that on StackOverflow already. HERE But I'd suggest you take the path of constructing a list of extensions and then checking agains each one of those. Regex would be more costly than that and would internally do roughly the same.

Community
  • 1
  • 1
Peter Perháč
  • 20,434
  • 21
  • 120
  • 152
0

You can use switch statement to validate file extension:

protected bool IsValidExtension(string extension)
{
  switch (extension.ToLower())
  {
    case ".jpg":
    case ".jpeg":
    case ".gif":
    case ".png":
    case ".bmp":
      return true;

    default:
      return false;
  }
}
SHS
  • 149
  • 6
0

Regular Expression.

    string fx = "jpg";
    if (!Regex.IsMatch(fx, "^\.?(jpg|jpeg|gif|png|bmp)$", RegexOptions.IgnoreCase))
    {

    }

also, to get the file extension, use

string fn= file.FileName;
if (fn.Contains("\\")) 
    fn= fn.Substring(fn.LastIndexOf("\\") + 1);

string fx = fn.Substring(0, fn.LastIndexOf('.'));
Christian
  • 3,708
  • 3
  • 39
  • 60
  • 1
    how about writing the code prior to posting the answer? (Not my downvote, but this is probably why you get them) – Avada Kedavra Oct 10 '11 at 08:54
  • Just to give the guy something to think about while I wrote the code. – Christian Oct 10 '11 at 08:55
  • 2
    The good news is that you can delete this and gain the peer pressure badge. But it's not generally accepted that you leave a placeholder answer that doesn't answer the question. – David Heffernan Oct 10 '11 at 08:56
  • :) Ok everybody picking on me. In the future, I shall only post an answer when I've written the code first hehe – Christian Oct 10 '11 at 09:00
  • 1
    Hehe, we are not picking on you, just stating that leaving a placeholder (as David writes) is not generally appreciated. Now. Your answer is legit and since your write that you'll think about that in the future, ill upvote it for you. :) – Avada Kedavra Oct 10 '11 at 09:03
  • @David: I dont suffer from peer pressure haha – Christian Oct 10 '11 at 09:08
  • 1
    To get the extension, don't use that code, simply use [`FileSystemInfo.Extension`](http://msdn.microsoft.com/en-us/library/system.io.filesysteminfo.extension.aspx). – CodeCaster Oct 10 '11 at 09:28
  • `FileSystemInfo.Extension` is fine so long as it originates as a file system object. If you have just a string, you need the above example. Also note that `FileSystemInfo.Extension` includes the . in the return – Christian Oct 10 '11 at 10:02
  • 1
    instead of `FileSystemInfo` there is also `Path.GetExtension(pathstring)`. much cleaner# – Firo Oct 11 '11 at 08:53
  • this is why i love SO :) so much input. Thanks Firo. – Christian Oct 11 '11 at 10:17