1

I need to remotely create directories on an SVN repository. The folders can contain special characters e.g. the vendor, driver and version directories in my example can contain one or more plus ("+") characters.

DoDontEscape() just combines the directories to an URL

DoEscape()

  • uses Uri.EscapeDataString() on the directories before combining it to an URI
  • throws a 'Path already exists' exception

Do I need to use Uri.EscapeDataString() on each directory before combining and constructing an Uri object? Or is just combining and constructing an Uri object OK?

I use SharpSVN library to remotely create directories and Flurl for combining to an URL.

Code

using SharpSvn;
using Flurl;

static readonly string reposRootString = @"https://my.svn.repos/Testing/";
static readonly string vendor = "Vendor";
static readonly string driver = "Driver+";
static readonly string version = "1.0.0.1";

static void Main(string[] args)
{
    DoDontEscape();
    DoEscape();

}

private static void DoDontEscape()
{
    string combined = Url.Combine(reposRootString, vendor, driver, version);
    TryCreateURI(combined);
}

private static void DoEscape()
{
    var vEscaped = Uri.EscapeDataString(vendor);
    var dEscaped = Uri.EscapeDataString(driver);
    var dvEscaped = Uri.EscapeDataString(version);

    string combined = Url.Combine(reposRootString, vEscaped, dEscaped, dvEscaped);
    TryCreateURI(combined);
}

private static void TryCreateURI(string combined)
{
    Uri uri;
    if (Uri.TryCreate(combined, UriKind.Absolute, out uri))
    {
        CreateSvnDir(uri);
    }
    else
    {
        throw new Exception(string.Format("{0} is an invalid URI!", combined));
    }
}

private static void CreateSvnDir(Uri uri)
{
    using (SvnClient client = new SvnClient())
        client.RemoteCreateDirectory(uri, new SvnCreateDirectoryArgs() { CreateParents = true, LogMessage = "create dir" });
}
Todd Menier
  • 37,557
  • 17
  • 150
  • 173
BertAR
  • 425
  • 3
  • 18

1 Answers1

0

Flurl's Url.Combine is very conservative about how it encodes path segments. If you include reserved characters (characters with special meaning such as "/" or "+"), it will assume you want to include them as-is and will not encode them. It will only encode illegal characters, such as spaces.

I'm guessing you want to encode reserved characters here, so your DoEscape() method looks correct. Note that Flurl has its own encoding method, Url.Encode, which is very similar to Uri.EscapeDataString except it overcomes a few quirks that may or may not affect you. Namely:

  1. Uri.EscapeDataString throws an exception when you hit 65,520 characters; Url.Encode does not.

  2. Uri.EscapeDataString does not give you an option to encode spaces as "+"; Url.Encode does.

Todd Menier
  • 37,557
  • 17
  • 150
  • 173