locked
Leading Backslash Dropped From Parameter Value RRS feed

  • Question

  • User-136133947 posted

    I have a restful Api where the controllers derive from ApiController. One of the controller actions has a string parameter which needs to accept a value that may start with a leading backslash. Ex: \Folder1\Item1

    I am using the HttpClient class to call the api method and the issue I am having is that the first backslash always gets removed and the other slashes get changed to forward slashes. The main concern is the first slash getting removed. Below is the action method:

            [Route("{*name}")]
            public HttpResponseMessage DeleteTest(string name)
            {
    
            }

    My client call looks like this:

    await client.DeleteAsync("api/test/\\Test\\Delete\\Test"));

    I get to the correct action, but the "name" parameter has the value of:

    Test/Delete/Test

    How can I get: /Test/Delete/Test or even better: \Test\Delete\Test?

    Wednesday, June 17, 2015 5:09 PM

All replies

  • User-103761908 posted

    I think you need to encode the file path you're passing in.

    eg.

    var file = System.Web.HttpUtility.UrlEncode(@"\Test\Delete\Test");
    await client.DeleteAsync("api/test/" + file);

    Monday, June 22, 2015 6:32 AM
  • User-136133947 posted

    I updated my server call to:

    await client.DeleteAsync(String.Format("api/test/{0}", System.Net.WebUtility.UrlEncode(@"\Test\Delete\Test")));

    However, I see the same result on the server:

    "Test/Delete/Test"

    I'm wondering if this is related to OData routing. I saw a note here that indicates you have to double encode slashes to get this to work. Although this would mean the client needs to send a value like:

    await client.DeleteAsync(String.Format("api/test/{0}", "%255CTest%255CDelete%255CTest"));


    Then the server would need to do a System.Net.WebUtility.UrlDecode(name); which all seems very ugly. I am wondering if someone can confirm if this is the only way or if there is a clean way of doing this?

    Monday, June 22, 2015 11:53 AM
  • User1644755831 posted

    Hello DeviantSpark,

    You could implement catch app parameter for this. By default web api routing does not include this but you can create a custom HttpParameterBinding to implement catch all parameter

    http://www.tugberkugurlu.com/archive/asp-net-web-api-catch-all-route-parameter-binding 

    Then you can pass this encoded value as query string parameter.

    Hope this helps.

    With Regards,

    Krunal Parekh

    Thursday, June 25, 2015 3:58 AM
  • User-136133947 posted

    Hi Krunal,

    I have an asterisk in my route currently [Route("{*name}")] which I think should be a catch all in web api 2?

    Friday, June 26, 2015 10:30 AM
  • User1644755831 posted

    Hello DeviantSpark,

    I have an asterisk in my route currently [Route("{*name}")] which I think should be a catch all in web api 2?

    Yes.

    Please see this. http://www.matrichard.com/post/WebAPI-catch-all-route-or-having-a-default-route-when-a-route-is-not-found

    Hope this helps.

    With Regards,

    Krunal Parekh

    Sunday, June 28, 2015 10:30 PM
  • User633086528 posted

    I will suggest you encode it with BASE64.

    var plainTextBytes = System.Text. Encoding.UTF8.GetBytes(path);
    var pathEncoded = System. Convert.ToBase64String(plainTextBytes);
    



    Monday, June 29, 2015 5:43 AM
  • User-136133947 posted

    Nitesh, I tried this but seem to see the same behavior. I encoded:

    "api/test/\file"

    Into

    "YXBpL3Rlc3QvDGlsZQ=="

    Then, the server shows the parameter value without the leading slash:

    file

    Thursday, July 2, 2015 1:47 PM