my js code:
var a = ["asdfa", "asdfa", "aaa"];
var data = [];
for (var i in a) data.push({ name: 'keys', value: a[i] });
$.post('<%=ResolveUrl("~/svc/aja.svc/GetMultiple") %>', $.param(data), function(d) {
//do stuff
});
my ajax enabled wcf
[ServiceContract(Namespace = "")]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class Aja
{
[WebInvoke(Method="POST")]
[OperationContract]
public IEnumerable<IdContent> GetMultiple(string[] keys)
{
return keys.Select(o => new IdContent { Id = o, Content = o + o });
}
I tried debugging and the Method GetMultiple
doesn't get hit,(I get error 500)
if I do this by sending a simple string not array, than it works
this the message that I get as a result in firebug :
{"ExceptionDetail":{"HelpLink":null,"InnerException":null,"Message":"The
incoming message has an unexpected message format 'Raw'. The expected
message formats for the operation are 'Xml'; 'Json'. This can be
because a WebContentTypeMapper has not been configured on the binding.
See the documentation of WebContentTypeMapper for more
details.","StackTrace":" at
System.ServiceModel.Dispatcher.DemultiplexingDispatchMessageFormatter.DeserializeRequest(Message
message, Object[] parameters)\u000d\u000a at
System.ServiceModel.Dispatcher.UriTemplateDispatchFormatter.DeserializeRequest(Message
message, Object[] parameters)\u000d\u000a at
System.ServiceModel.Dispatcher.CompositeDispatchFormatter.DeserializeRequest(Message
message, Object[] parameters)\u000d\u000a at
System.ServiceModel.Dispatcher.DispatchOperationRuntime.DeserializeInputs(MessageRpc&
rpc)\u000d\u000a at
System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc&
rpc)\u000d\u000a at
System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc&
rpc)\u000d\u000a at
System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage4(MessageRpc&
rpc)\u000d\u000a at
System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean
isOperationContextSet)","Type":"System.InvalidOperationException"},"ExceptionType":"System.InvalidOperationException","Message":"The
incoming message has an unexpected message format 'Raw'. The expected
message formats for the operation are 'Xml'; 'Json'. This can be
because a WebContentTypeMapper has not been configured on the binding.
See the documentation of WebContentTypeMapper for more
details.","StackTrace":" at
System.ServiceModel.Dispatcher.DemultiplexingDispatchMessageFormatter.DeserializeRequest(Message
message, Object[] parameters)\u000d\u000a at
System.ServiceModel.Dispatcher.UriTemplateDispatchFormatter.DeserializeRequest(Message
message, Object[] parameters)\u000d\u000a at
System.ServiceModel.Dispatcher.CompositeDispatchFormatter.DeserializeRequest(Message
message, Object[] parameters)\u000d\u000a at
System.ServiceModel.Dispatcher.DispatchOperationRuntime.DeserializeInputs(MessageRpc&
rpc)\u000d\u000a at
System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc&
rpc)\u000d\u000a at
System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc&
rpc)\u000d\u000a at
System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage4(MessageRpc&
rpc)\u000d\u000a at
System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean
isOperationContextSet)"}
Best Answer
The problem you're having: $.post sends data encoded in application/x-www-form-urlencoded, and this format is not supported natively by WCF. That's the issue.
Now for solutions: as often is the case with WCF, there are quite a few things you can do:
1) Change the client side to send some format which the service can understand. WCF understands JSON, so you can use a JSON stringifier (i.e., JSON.stringify from json2.js from Crockford's implementation). With this, you'd need to change the code to use $.ajax instead of the "shortcut" $.post:
2) "Teach" WCF how to understand the native format for the $.params (or $.post) calls. There are two ways to do that:
2.1) Do it "by hand". It's not very trivial, but it can be done. You'll need an
IDispatchMessageFormatter
which can convert from the forms/encoded into thestring[]
parameter for your operation. You'd then need a behavior to hook this new format up and either a new service host factory (to hook the behavior via code) or a behavior config extension (if you want to do it in config). The following links are for posts explaining in more details the message formatters, the endpoint behaviors, the service host factory and the behavior config extensions. The code below shows one possible implementation for a dispatch formatter which knows how to deal with string arrays.2.2) Use the new "jQuery support for WCF" which is published on http://wcf.codeplex.com. Those are some behaviors / formatters which add support for forms/urlencoded requests. But you'll need to change the operation to receive the data in an untyped way (i.e., as a
JsonArray
), and in the code you'd enumerate the items yourself.