Reputation: 19684
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
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
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