none
Special Characters in the url RRS feed

  • Question

  • I have a WCF service hosted in IIS... 

    Is it possible to receive special characters in the url without using query string parameters ?

    For example....

    For an endpoint /partNumber/{id} where the part number is ABC/123 

    The actual request comes in as /partNumber/ABC%2F123 

    Is there something in the service I can do to accept this request ? 

     


    Thursday, October 10, 2013 12:50 PM

Answers

  • Hi,

    Please try to modify your web configure file as below:

    <uri>
      <schemeSettings>
        <clear />
        <add name="http" genericUriParserOptions="DontUnescapePathDotsAndSlashes" />
        <add name="https" genericUriParserOptions="DontUnescapePathDotsAndSlashes" />
      </schemeSettings>
    </uri>
    
    <system.net>
      <settings>
        <httpListener unescapeRequestUrl="false"/>
      </settings>
    </system.net>
    

    For more information, please try to check:
    #GenericUriParserOptions:
    http://msdn.microsoft.com/en-us/library/system.genericuriparseroptions.aspx .

    Here is a similar thread:
    http://social.msdn.microsoft.com/Forums/vstudio/en-US/d03c8331-1e98-4d5d-82a7-390942a93012/special-characters-in-wcf-rest-atom-feed?forum=wcf .

    Best Regards,
    Amy Peng


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    Friday, October 11, 2013 2:53 AM
    Moderator
  • Hi, 

    Since you are appear to be not having luck with the config file options, I found this code below will send the GET request to http://localhost:8000/Service/EchoString?text=Hello%26World%23here (param = "Hello&World#here".), it is similar to your scenario, hope it can help you to get start:
    <p>    public class Post_1<br/>    {
            [ServiceContract]
            public interface ITest
            {
                [OperationContract, WebGet]
                string EchoString(string text);
            }
            public class Service : ITest
            {
                public string EchoString(string text)
                {
                    return text;
                }
            }
            public static void Test()
            {
                string baseAddress = "http://" + Environment.MachineName + ":8000/Service";
                ServiceHost host = new ServiceHost(typeof(Service), new Uri(baseAddress));
                host.AddServiceEndpoint(typeof(ITest), new WebHttpBinding(), "").Behaviors.Add(new WebHttpBehavior());
                host.Open();
                Console.WriteLine("Host opened");
    
                string param = "Hello&World#here";
                string escaped = Uri.EscapeDataString(param);
                Util.SendRequest(baseAddress + "/EchoString?text=" + escaped, "GET", null, null);
    
                Console.Write("Press ENTER to close the host");
                Console.ReadLine();
                host.Close();
            }
        }
        public static class Util
        {
            public static string SendRequest(string uri, string method, string contentType, string body)
            {
                string responseBody = null;
    
                HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(uri);
                req.Method = method;
                if (!String.IsNullOrEmpty(contentType))
                {
                    req.ContentType = contentType;
                }
                if (!String.IsNullOrEmpty(body))
                {
                    byte[] bodyBytes = Encoding.UTF8.GetBytes(body);
                    req.GetRequestStream().Write(bodyBytes, 0, bodyBytes.Length);
                    req.GetRequestStream().Close();
                }
    
                HttpWebResponse resp;
                try
                {
                    resp = (HttpWebResponse)req.GetResponse();
                }
                catch (WebException e)
                {
                    resp = (HttpWebResponse)e.Response;
                }
                Console.WriteLine("HTTP/{0} {1} {2}", resp.ProtocolVersion, (int)resp.StatusCode, resp.StatusDescription);
                foreach (string headerName in resp.Headers.AllKeys)
                {
                    Console.WriteLine("{0}: {1}", headerName, resp.Headers[headerName]);
                }
                Console.WriteLine();
                Stream respStream = resp.GetResponseStream();
                if (respStream != null)
                {
                    responseBody = new StreamReader(respStream).ReadToEnd();
                    Console.WriteLine(responseBody);
                }
                else
                {
                    Console.WriteLine("HttpWebResponse.GetResponseStream returned null");
                }
                Console.WriteLine();
                Console.WriteLine("  *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*  ");
                Console.WriteLine();
    
                return responseBody;
            }
        }</p>
    

    Best Regards,
    Amy Peng


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.


    Wednesday, October 16, 2013 9:25 AM
    Moderator

All replies

  • Hi,

    Please try to modify your web configure file as below:

    <uri>
      <schemeSettings>
        <clear />
        <add name="http" genericUriParserOptions="DontUnescapePathDotsAndSlashes" />
        <add name="https" genericUriParserOptions="DontUnescapePathDotsAndSlashes" />
      </schemeSettings>
    </uri>
    
    <system.net>
      <settings>
        <httpListener unescapeRequestUrl="false"/>
      </settings>
    </system.net>
    

    For more information, please try to check:
    #GenericUriParserOptions:
    http://msdn.microsoft.com/en-us/library/system.genericuriparseroptions.aspx .

    Here is a similar thread:
    http://social.msdn.microsoft.com/Forums/vstudio/en-US/d03c8331-1e98-4d5d-82a7-390942a93012/special-characters-in-wcf-rest-atom-feed?forum=wcf .

    Best Regards,
    Amy Peng


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    Friday, October 11, 2013 2:53 AM
    Moderator
  • Thanks for the response....

    I just want to make sure I understand....

    Is there anything that can be done within the WCF service in order to receive the following request ?

    The actual request comes in as /partNumber/ABC%2F123   (which inside the service would be read as ABC/123)   

    A request that uses "query strings" comes in as such /path/?query_string (i.e., includes a ? mark, correct)

    Can you encode a rest endpoint that does not use query strings.  

    I do not appear to be having luck with the config file options


    Saturday, October 12, 2013 7:38 PM
  • Hi, 

    Since you are appear to be not having luck with the config file options, I found this code below will send the GET request to http://localhost:8000/Service/EchoString?text=Hello%26World%23here (param = "Hello&World#here".), it is similar to your scenario, hope it can help you to get start:
    <p>    public class Post_1<br/>    {
            [ServiceContract]
            public interface ITest
            {
                [OperationContract, WebGet]
                string EchoString(string text);
            }
            public class Service : ITest
            {
                public string EchoString(string text)
                {
                    return text;
                }
            }
            public static void Test()
            {
                string baseAddress = "http://" + Environment.MachineName + ":8000/Service";
                ServiceHost host = new ServiceHost(typeof(Service), new Uri(baseAddress));
                host.AddServiceEndpoint(typeof(ITest), new WebHttpBinding(), "").Behaviors.Add(new WebHttpBehavior());
                host.Open();
                Console.WriteLine("Host opened");
    
                string param = "Hello&World#here";
                string escaped = Uri.EscapeDataString(param);
                Util.SendRequest(baseAddress + "/EchoString?text=" + escaped, "GET", null, null);
    
                Console.Write("Press ENTER to close the host");
                Console.ReadLine();
                host.Close();
            }
        }
        public static class Util
        {
            public static string SendRequest(string uri, string method, string contentType, string body)
            {
                string responseBody = null;
    
                HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(uri);
                req.Method = method;
                if (!String.IsNullOrEmpty(contentType))
                {
                    req.ContentType = contentType;
                }
                if (!String.IsNullOrEmpty(body))
                {
                    byte[] bodyBytes = Encoding.UTF8.GetBytes(body);
                    req.GetRequestStream().Write(bodyBytes, 0, bodyBytes.Length);
                    req.GetRequestStream().Close();
                }
    
                HttpWebResponse resp;
                try
                {
                    resp = (HttpWebResponse)req.GetResponse();
                }
                catch (WebException e)
                {
                    resp = (HttpWebResponse)e.Response;
                }
                Console.WriteLine("HTTP/{0} {1} {2}", resp.ProtocolVersion, (int)resp.StatusCode, resp.StatusDescription);
                foreach (string headerName in resp.Headers.AllKeys)
                {
                    Console.WriteLine("{0}: {1}", headerName, resp.Headers[headerName]);
                }
                Console.WriteLine();
                Stream respStream = resp.GetResponseStream();
                if (respStream != null)
                {
                    responseBody = new StreamReader(respStream).ReadToEnd();
                    Console.WriteLine(responseBody);
                }
                else
                {
                    Console.WriteLine("HttpWebResponse.GetResponseStream returned null");
                }
                Console.WriteLine();
                Console.WriteLine("  *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*  ");
                Console.WriteLine();
    
                return responseBody;
            }
        }</p>
    

    Best Regards,
    Amy Peng


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.


    Wednesday, October 16, 2013 9:25 AM
    Moderator
  • Thanks once again for responding ...  I appreciate it...

    I am wondering if the hosting environment matters in this case.  Can this example be applied within an IIS setting ?  It looks as though the example is using a self-hosted option.  

    Where would the ("redirection code" ?) live in the IIS hosted WCF service code ?  

    [ServiceContract(@namespace = "")]
    public interface ITEST
    {
    [OperationContract()]
    [WebGet(UriTemplate = "/part/{id}", responseformat = WebMessageFormat.Json)]
    List<PART> PARTTHINGY(string part);

    }

    public List<PART> PARTTHINGY(string part)
    {
    return PART(part);
    }

    I have seen many articles stating that these characters are security risks.   I am wondering if the best option is to disallow them ? Would that be the recommended course of action ? 



    Wednesday, October 16, 2013 2:03 PM
  • Hi,

    It should be work in IIS setting.

    The following should be best to work:

    <uri>
      <schemeSettings>
        <clear />
        <add name="http" genericUriParserOptions="DontUnescapePathDotsAndSlashes" />
        <add name="https" genericUriParserOptions="DontUnescapePathDotsAndSlashes" />
      </schemeSettings>
    </uri>
    
    <system.net>
      <settings>
        <httpListener unescapeRequestUrl="false"/>
      </settings>
    </system.net>

    But you can not use the configure file, so the code post by @amy should work for you.

    Monday, October 21, 2013 5:22 AM