2

I've read a few questions that answer this, and I understand the regular expression I'm required to use, however actually applying it in MVC is where I stumble. I will also preface by saying I am terrible at regular expressions so far.

I'm writing a file upload application in MVC and I want to apply standard windows filename validation. \/:*?"<>| are invalid characters anywhere in the name.

My View Model for this is setup like so, using a different regex I found:

    public class FileRenameModel
{
    [RegularExpression(@"^[\w\-. ]+$", ErrorMessage="A filename cannot contain \\ / : * ? \" < > |")]
    [Required]
    public string Filename { get; set; }
    [Required]
    public int FileID      { get; set; }
}

Whenever I try to change the regex to @"^[\\/:?"<>|]+$ the " in the middle kills it and throws an error. I haven't figured out how to properly escape it so that I can include it in the string. When I use the regex without the " it tells me any string I put into the textbox fails. Am I using the ^ incorrectly?

2 Answers 2

4

Use double "" to escape quotes after starting a string with @.

To search for anything except you'd want to insert an additional ^ inside the brackets to create an except for match: @"^[^\\/:?""<>|]+$" Keep the ^ at the beginning as well to match the start of line.

Having said that, keep in mind for validation that browsers handle file names differently. Some older browsers sent a path along with the filename, that might break your validation for a legitimate file.

Sign up to request clarification or add additional context in comments.

4 Comments

This part has helped me with the ", thank you. However I'm still unfortunately stuck on the logic.
Thank you Paul. I ended up trying this just before checking your comment and it worked, but now I have an explanation as to why to do it that way. I will have to check for my validation breaking a legitimate file name.
Yeah, USUALLY this will work, but like I said some browsers send either the actual path or prepend some weirdness like ://. If you can, it might be best just to sanitize the filename in the request handler by removing any of the characters returned by System.IO.Path.GetInvalidPathChars().
I totally just realized that I've actually implemented sanitation. Not enough coffee this morning. Thanks again, it's a good learning experience for me.
1

This regular expression should match a more-than-sufficient subset of valid NTFS filenames (bear in mind that an NTFS file name may contain pretty much any Unicode character.)

Regex rxValidFileName = new Regex(@"^[[\p{IsBasicLatin}\p{IsLatin-1Supplement}\p{IsLatinExtended-A}\p{IsLatinExtended-B}]-[\p{C}<>:""/\|?*]]+$" , RegexOptions.IgnorePatternWhitespace|RegexOptions.IgnoreCase);

What this matches:

  • start-of-line, followed by
  • 1 or more of
    • any basic latin, latin-1 supplement, or latin extended-A or -B character, unless...
    • unless it's a C0 or C1 control character or one of the characters otherwise disallowed by NTFS — <>:"/\|?*
  • terminated by end-of-line.

Note that this matches a file name, not a file path. A file path is more complicated, since it's got a grammar to it, something like this, in crude ABNF:

filepath : relative-path
         | absolute-path
         | drivespecifier (relative-path|absolute-path)?
         | unc-share (absolute-path)?
         ;

relative-path : filename ( directory-separator filename? )*

absolute-path : directory-separator ( filename? directory-separator )*

directory-separator : [/\]

drivespecifier : [a-zA-Z] ":"

unc-share : "\\" filename "\" filename absolute-path?

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.