Nick
Nick

Reputation: 19684

jQuery Ajax - Why do I get a 404 when URL includes encoded #'s?

I have a RESTful WCF service that I am performing a PUT to using jQuery.ajax() One of my operations takes 5 strings as parameters. This operation performs tasks on RDF documents and therefore some of these parameters include (#) in the string. To accommodate this I am encoding these parameters.

My problem is when the url contains these encoded parameters the request fails with a 404. For testing purposes I have omitted the # and the request performs normally. I don't understand why the encoded # (%23) results in a 404. Can someone help me understand what's wrong?

The operation:

    [OperationContract]
    [CorsBehavior]
    [WebInvoke(Method = "PUT", UriTemplate = "Graphs/{library}/{subjectLocalPart}/{predicateLocalPart}/{objectPart}/{languageCode}")]
    ResultMessage CreateTriple(string library, string subjectLocalPart, string predicateLocalPart, string objectPart, string languageCode);

404:

http://localhost:1605/Service.svc/Graphs/myLib/123abc/content%23HasA/456def%23ghik/en-us

Works:

http://localhost:1605/Service.svc/Graphs/myLib/123abc/contentHasA/456defghik/en-us

Upvotes: 0

Views: 409

Answers (2)

carlosfigueira
carlosfigueira

Reputation: 87293

As another answer pointed out, the two URLs below are essentially the same

http://localhost:1605/Service.svc/Graphs/myLib/123abc/content%23HasA/456def%23ghik/en-us
http://localhost:1605/Service.svc/Graphs/myLib/123abc/content#HasA/456def#ghik/en-us

If you want to send '#' in the URI, you need to escape the escaped version, so that when it's unescaped at the server, it will be what you expect:

http://localhost:1605/Service.svc/Graphs/myLib/123abc/content%2523HasA/456def%2523ghik/en-us

Upvotes: 1

kamranicus
kamranicus

Reputation: 4417

I will put my comment into the form of an answer.

Even though it appears URL-encoded to you, the translated URL is as follows:

http://localhost:1605/Service.svc/Graphs/myLib/123abc/content#HasA/456def#ghik/en-us

Thus, your "page" is actually 123abc/content which is why it's a 404.

To solve this, use parameters and a DTO (domain object or class) as a parameter in your WCF service method. It can be JSON or name=value pairs; personally I'd use JSON.

[OperationContract]
[CorsBehavior]
[WebInvoke(Method = "PUT", UriTemplate = "Graphs/{library}/triple")]
ResultMessage CreateTriple(string library, TripleModel model);

[DataContract]
public class TripleModel {  
    [DataMember]
    public string SubjectLocalPart { get; set; }

    [DataMember]
    public string PredicateLocalPart { get; set; }

    [DataMember]
    public string ObjectPart { get; set; }

    [DataMember]
    public string LanguageCode { get; set; }
}

I haven't 100% tested this, but double-check using Fiddler just to make sure this is the case. I am guessing based on prior experience and by what you've given us.

Upvotes: 0

Related Questions