Paul Johnson
Paul Johnson

Reputation: 1418

How to make filenames web safe using c#

This is not about encoding URLs its more to do with a problem I noticed where you can have a valid filename on IIS sucha as "test & test.jpg" but this cannot be downloaded due to the & causing an error. There are other characters that do this also that are valid in windows but not for web.

My quick solution is to change the filename before saving using a regex below...

    public static string MakeFileNameWebSafe(string fileNameIn)
    {
        string pattern = @"[^A-Za-z0-9. ]";
        string safeFilename = System.Text.RegularExpressions.Regex.Replace(fileNameIn, pattern, string.Empty);
        if (safeFilename.StartsWith(".")) safeFilename = "noname" + safeFilename;

        return safeFilename;
    }

but I was wondering if there were any better built in ways of doing this.

Upvotes: 1

Views: 2708

Answers (5)

pwhe23
pwhe23

Reputation: 1334

Here's the one I use:

public static string MakeFileNameWebSafe(string path, string replace, string other)
{
    var folder = System.IO.Path.GetDirectoryName(path);
    var name = System.IO.Path.GetFileNameWithoutExtension(path);
    var ext = System.IO.Path.GetExtension(path);
    if (name == null) return path;
    var allowed = @"a-zA-Z0-9" + replace + (other ?? string.Empty);
    name = System.Text.RegularExpressions.Regex.Replace(name.Trim(), @"[^" + allowed + "]", replace);
    name = System.Text.RegularExpressions.Regex.Replace(name, @"[" + replace + "]+", replace);
    if (name.EndsWith(replace)) name = name.Substring(0, name.Length - 1);
    return folder + name + ext;
}

Upvotes: 1

Paul Johnson
Paul Johnson

Reputation: 1418

Just looking back at this question since its fairly popular. Just though I would post my current solution up here with various overloads for anyone who wants it..

public static string MakeSafeFilename(string filename, string spaceReplace)
    {
        return MakeSafeFilename(filename, spaceReplace, false, false);
    }

    public static string MakeSafeUrlSegment(string text)
    {
        return MakeSafeUrlSegment(text, "-");
    }

    public static string MakeSafeUrlSegment(string text, string spaceReplace)
    {
        return MakeSafeFilename(text, spaceReplace, false, true);
    }

    public static string MakeSafeFilename(string filename, string spaceReplace, bool htmlDecode, bool forUrlSegment)
    {
        if (htmlDecode)
            filename = HttpUtility.HtmlDecode(filename);
        string pattern = forUrlSegment ? @"[^A-Za-z0-9_\- ]" : @"[^A-Za-z0-9._\- ]";
        string safeFilename = Regex.Replace(filename, pattern, string.Empty);

        safeFilename = safeFilename.Replace(" ", spaceReplace);

        return safeFilename;
    }

Upvotes: 3

Darkwing
Darkwing

Reputation: 7595

I think you are referring to the "A potentially dangerous Request.Path value was detected from the client (%)" error which Asp.Net throws for paths which include characters which might indicate cross site scripting attempts:

there is a good article on how to work around this:

http://www.hanselman.com/blog/ExperimentsInWackinessAllowingPercentsAnglebracketsAndOtherNaughtyThingsInTheASPNETIISRequestURL.aspx

Upvotes: 1

Roy Dictus
Roy Dictus

Reputation: 33149

Built-in I don't know about.

What you can do is, like you say, scan the original filename and generate a Web-safe version of it.

For such Web-safe versions, you can make it appear like slugs in blogs and blog categories (these are search engine-optimized):

  • Only lowercase characters
  • Numbers are allowed
  • Dashes are allowed
  • Spaces are replaced by dashes
  • Nothing else is allowed
  • Possibly you could replace "&" by "-and-"

So "test & test.jpg" would translate to "test-and-test.jpg".

Upvotes: 3

Barry Kaye
Barry Kaye

Reputation: 7759

If you are not concerned to keep the original name perhaps you could just replace the name with a guid?

Upvotes: 0

Related Questions