locked
Keys with forward slashes do not work in WCF Data Services RRS feed

  • Question

  • Hello,

    I have a (relatively) simple Linq-to-SQL model set up on top of a third party database.  This database has key fields that can contain forward slashes.  Unfortunately I'm not in a position to change these key fields, so my data service has to somehow give access to them.

    I am using the Visual Studio 2010 RC (4.0.30128 RC1Rel) on Windows 7 x64.

    I read around a bit, and it seems that I should be able to use the following in web.config to get it 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>
    I have tried this, and I'm still getting errors when attempting to access data objects with these keys.  An example of a couple of URIs:

    http://localhost:65104/MyService.svc/Sets('2009/2010') http://localhost:65104/MyService.svc/Sets('2009%2F2010'
    )

    It also fails in code:
    MyDataContext dc = new MyDataContext(new Uri("http://localhost:65104/MyService.svc"));            
    
    var s = dc.Sets.Where(s => s.SetId == "2009/2010").First();
    
    
    Both of the following URIs work, which leads me to believe the issue is definitely caused by the forward slash in the key:


    http://localhost:65104/MyService.svc/Sets()?$filter=startswith(SetId,'2009')
    
    http://localhost:65104/MyService.svc/Sets()?$filter=YearStart eq 2009


    In all cases, the error returned by the data service is "400 Bad Request."

    Any help would be greatly appreciated! :)
    Monday, March 15, 2010 11:19 PM

All replies

  • Hi,

    It seems you're using the ASP.NET developer web server to host your service. This web server has many known limitations. This might be one of them (I didn't try it though). Could you try hosting your service on IIS and see if it works? (That usually fixes lot of these types of issues).

    Thanks,
    Vitek Karas [MSFT]
    Tuesday, March 16, 2010 9:55 AM
    Moderator
  • Hello,

    Thanks for the suggestion! I have moved to hosting on IIS as suggested.  Unfortunately the error still remains, both when accessing in code and when attempting to use the URI (which now look like e.g. http://localhost/MyDataService/MyService.svc/Sets('2009%2F2010'))

    If I browse /Sets, it seems like the service is now returning the right URIs:

    ...
    <id>http://localhost/MyDataService/MyService.svc/Sets('2006%2F2007')</id>
    ...

    I should point out that the error is being returned in XML format by the data service:

    <?
    xml version="1.0" encoding="utf-8" standalone="yes" ?>
    <error xmlns="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">
      <code />
      <message xml:lang="en-US">Bad Request - Error in query syntax.</message>
    </error>


    Any further suggestions?

    Thanks for your time. :)
    Tuesday, March 16, 2010 10:52 AM
  • Hi Jon,

    I'm investigating this problem right now. I'll let you know if I come to a conclusion.

    Regards,

    PQ


    Peter Q. http://blogs.msdn.com/peter_qian
    Friday, March 26, 2010 1:14 AM
    Answerer
  • Hi Jon,

     

    I have some resolution to this problem, although it may be hacky:

    http://blogs.msdn.com/peter_qian/archive/2010/03/26/allowing-special-characters-as-keys-in-wcf-data-services-over-asp-net.aspx

     

    Regards,

    PQ


    Peter Q. http://blogs.msdn.com/peter_qian
    Friday, March 26, 2010 2:53 AM
    Answerer
  • Peter, I am having the exact same issue.  What is this "hacky" solution of which you speak?  The link above is dead.
    Tuesday, August 9, 2011 4:56 PM
  • Peter, I have the same issue, and the link you gave is dead.  Could you advise what the workaround is?

    Thanks!

    Thursday, August 11, 2011 9:35 AM
  • Hi 

    Peter I have exactly the same issue and have followed the steps described in your blog but some of the characters are still not working. Having trouble with the following characters '%', '#', '/', '\', '?'. To get the '%' working I added the following to the web.config:

    <httpRuntime requestPathInvalidCharacters="" requestValidationMode="2.0"/> <pages validateRequest="false"/>

    This fixed  "&", "*", ":", "<", ">" and "+" but "%" still doesn't work. I'm trying to access a security where the primary key = '2d%f8db8':

    http://uk-lin-w001/securities(SQLA)MSMQ/SecurityModelService.svc/Securities('2d%f8db8')

    but on the server the URi comes out as:

    http://uk-lin-w001:80/securities(SQLA)MSMQ/SecurityModelService.svc/Securities('2dødb8')

    Which doesnt exist and hence get  "Resource not found for the segment 'Securities'" error.

    To get '#', '/', '\', '?' working  I added the following to the constructor of my data service:

    public WcfDataService1() 
    { 
        string uri = HttpContext.Current.Request.Url.OriginalString; 
        StringBuilder replaceUri = new StringBuilder();
    bool inquote = false; for (int i = 0; i < uri.Length; ++i) { switch (uri[i]) { case '\'': replaceUri.Append(uri[i]); inquote = !inquote; break; case '#': case '\\': case '/': case '?': if (inquote) { replaceUri.AppendFormat("%{0:X}", (int)uri[i]); } else { replaceUri.Append(uri[i]); }
    break; default: replaceUri.Append(uri[i]); break; } }
    OperationContext.Current.IncomingMessageProperties["MicrosoftDataServicesRequestUri"] = new Uri(replaceUri.ToString()); }

    However HttpContext.Current.Request.Url.OriginalString returns the escaped version and not the unescaped version. I request the following through the internet browser:

    http://uk-lin-w001/securities(SQLA)MSMQ/SecurityModelService.svc/Securities('OBL%203.75%20#28')

    but HttpContext.Current.Request.Url.OriginalString returns:

    http://uk-lin-w001:80/securities(SQLA)MSMQ/SecurityModelService.svc/Securities('OBL 3.75

    Do I need to configure something on the IIS to get this working?

    Thursday, March 8, 2012 4:24 PM