我的js代码:
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
});
我的ajax已启用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 });
}
我尝试了调试,方法GetMultiple
没有被击中,(我得到错误500)
如果我这样做是通过发送一个简单的字符串而不是数组,而不是它的工作
这是我在firebug中得到的消息:
{ “ExceptionDetail”:{ “HELPLINK”:空 “的InnerException”:空, “消息”:“的 传入消息具有意外的消息格式“原始”。预期的 操作的消息格式是'Xml'; 'Json的'。这可以 因为尚未在绑定上配置WebContentTypeMapper。 有关更多信息,请参阅WebContentTypeMapper的文档 详情。“,”StackTrace“:”at System.ServiceModel.Dispatcher.DemultiplexingDispatchMessageFormatter.DeserializeRequest(消息 消息,对象[]参数)\ u000d \ u000a at System.ServiceModel.Dispatcher.UriTemplateDispatchFormatter.DeserializeRequest(消息 消息,对象[]参数)\ u000d \ u000a at System.ServiceModel.Dispatcher.CompositeDispatchFormatter.DeserializeRequest(消息 消息,对象[]参数)\ 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(布尔 isOperationContextSet) “ ”类型“: ”System.InvalidOperationException“}, ”ExceptionType“: ”System.InvalidOperationException“, ”消息“:” 的 传入消息具有意外的消息格式“原始”。预期的 操作的消息格式是'Xml'; 'Json的'。这可以 因为尚未在绑定上配置WebContentTypeMapper。 有关更多信息,请参阅WebContentTypeMapper的文档 详情。“,”StackTrace“:”at System.ServiceModel.Dispatcher.DemultiplexingDispatchMessageFormatter.DeserializeRequest(消息 消息,对象[]参数)\ u000d \ u000a at System.ServiceModel.Dispatcher.UriTemplateDispatchFormatter.DeserializeRequest(消息 消息,对象[]参数)\ u000d \ u000a at System.ServiceModel.Dispatcher.CompositeDispatchFormatter.DeserializeRequest(消息 消息,对象[]参数)\ 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(布尔 isOperationContextSet)“}
答案 0 :(得分:5)
您遇到的问题:$ .post发送以application / x-www-form-urlencoded编码的数据,WCF本身不支持此格式。这就是问题所在。
现在寻求解决方案:与WCF一样,您可以做很多事情:
1)更改客户端以发送服务可以理解的格式。 WCF理解JSON,因此您可以使用JSON字符串(即json2.js from Crockford's implementation中的JSON.stringify)。有了这个,您需要更改代码以使用$ .ajax而不是“快捷方式”$ .post:
$.ajax({
type: "POST",
url: '<%=ResolveUrl("~/svc/aja.svc/GetMultiple") %>',
contentType: "application/json",
data: JSON.stringify({ keys: a }),
success: function (result) {
alert(result);
}
});
2)“教”WCF如何理解$ .params(或$ .post)调用的原生格式。有两种方法可以做到这一点:
2.1)“手动”做。这不是很微不足道,但可以做到。您需要一个IDispatchMessageFormatter
,它可以从表单/编码转换为您的操作的string[]
参数。然后,您需要一种行为来挂接这种新格式,以及新服务主机工厂(通过代码挂钩行为)或行为配置扩展(如果您想在配置中执行此操作)。以下链接适用于更详细解释message formatters,endpoint behaviors,service host factory和behavior config extensions的帖子。下面的代码显示了调度格式化程序的一种可能实现,它知道如何处理字符串数组。
public class AjaServiceHostFactory : ServiceHostFactory
{
protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
{
return new AjaServiceHost(serviceType, baseAddresses);
}
public class AjaServiceHost : ServiceHost
{
public AjaServiceHost(Type serviceType, Uri[] baseAddresses)
: base(serviceType, baseAddresses) { }
protected override void OnOpening()
{
base.OnOpening();
ServiceEndpoint endpoint = this.AddServiceEndpoint(typeof(Aja), new WebHttpBinding(), "");
endpoint.Behaviors.Add(new WebScriptEnablingBehavior());
endpoint.Behaviors.Add(new MyFormsUrlEncodedAwareBehavior());
}
}
}
class MyFormsUrlEncodedAwareBehavior : IEndpointBehavior
{
public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
{
}
public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
{
}
public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
{
foreach (var operation in endpoint.Contract.Operations)
{
var dispatchOperation = endpointDispatcher.DispatchRuntime.Operations[operation.Name];
dispatchOperation.Formatter = new MyFormsUrlEncodedAwareFormatter(operation, dispatchOperation.Formatter);
}
}
public void Validate(ServiceEndpoint endpoint)
{
}
}
class MyFormsUrlEncodedAwareFormatter : IDispatchMessageFormatter
{
private OperationDescription operationDescription;
private IDispatchMessageFormatter originalFormatter;
public MyFormsUrlEncodedAwareFormatter(OperationDescription operationDescription, IDispatchMessageFormatter originalFormatter)
{
this.operationDescription = operationDescription;
this.originalFormatter = originalFormatter;
}
public void DeserializeRequest(Message message, object[] parameters)
{
if (message.Properties.ContainsKey(WebBodyFormatMessageProperty.Name))
{
var bodyFormat = (WebBodyFormatMessageProperty)message.Properties[WebBodyFormatMessageProperty.Name];
if (bodyFormat.Format == WebContentFormat.Raw)
{
if (message.Properties.ContainsKey(HttpRequestMessageProperty.Name))
{
var httpReq = (HttpRequestMessageProperty)message.Properties[HttpRequestMessageProperty.Name];
if (httpReq.Headers[HttpRequestHeader.ContentType] == "application/x-www-form-urlencoded")
{
var requestBodyParts = operationDescription.Messages[0].Body.Parts;
if (requestBodyParts.Count == 1 && requestBodyParts[0].Type == typeof(string[]))
{
string body = GetRawMessageBodyAsString(message);
NameValueCollection pairs = HttpUtility.ParseQueryString(body);
parameters[0] = pairs.GetValues(requestBodyParts[0].Name);
return;
}
}
}
}
}
this.originalFormatter.DeserializeRequest(message, parameters);
}
private string GetRawMessageBodyAsString(Message message)
{
XmlDictionaryReader reader = message.GetReaderAtBodyContents();
reader.ReadStartElement("Binary");
byte[] bytes = reader.ReadContentAsBase64();
return Encoding.UTF8.GetString(bytes);
}
public Message SerializeReply(MessageVersion messageVersion, object[] parameters, object result)
{
return this.originalFormatter.SerializeReply(messageVersion, parameters, result);
}
}
2.2 )使用http://wcf.codeplex.com上发布的新“jCF支持WCF”。这些是一些行为/格式化程序,它们增加了对表单/ urlencoded请求的支持。但是您需要更改操作以无类型方式接收数据(即,作为JsonArray
),并且在代码中您自己枚举项目。
答案 1 :(得分:1)
我认为你应该使用你试图作为参数传递给wcf应用程序的数组创建一个JSON字符串。请尝试以下代码
Javascript部分,
var list = ["a", "b", "c", "d"];
var jsonText = JSON.stringify({ list: list });
$.ajax({
type: "POST",
url: "WebService1.svc/methodName",
data: jsonText,
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function() { alert("it worked"); },
failure: function() { alert("Uh oh"); }
});
希望这会有所帮助......
答案 2 :(得分:1)
这是不可能的。
您无法将值数组从URL映射到参数。
如果要传递数组,请使用HTTP POST 。
的编辑:强> 的
为你演示〜
使用mvc2~
成功的关键是traditional
将traditional
参数设置为true
$(function(){
var a = [1, 2];
$.ajax({
type: "POST",
url: "<%= ResolveUrl("~/Home/PostArray/") %>",
data: {orderedIds: a},
dataType: "json",
traditional: true,
success: function(msg){alert(msg)}
});
})
由于jquery 1.4存在此参数,因为将对象序列化为查询参数的机制已更改。
并且行动是〜
[HttpPost]
public ActionResult PostArray(int[] orderedIds)
{
return Content(orderedIds.Length.ToString());
}
希望有帮助~`
答案 3 :(得分:1)
尝试保持服务器端代码相同,并将客户端代码更改为:
$(function(){
var a = ["asdfa", "asdfa", "aaa"];
var data = [];
for (var i in a) data.push({ name: 'keys', value: a[i] });
$.ajax({
url: "echo/json/",
data: data,
dataType: "json",
traditional: true,
success: function(msg){alert(msg)}
});
})
我认为您的问题可能是使用$.post
方法时未正确指定内容类型。
答案 4 :(得分:0)
您也可以尝试
var objSearch = [
{ "Key": "Key_Name1", "Value": "asdfa"},
{ "Key": "Key_Name2", "Value": "asdfa"},
{ "Key": "Key_Name3", "Value": "aaa"},
];
此处Key_Name表示您加入了wcf Lke(键=>“ Keyname1”,Value =>“ asdfa”)
$.ajax({
type: "POST",
url: svcCertificateUrl + '/Fetch',
contentType: "application/json; charset=utf-8",
dataType: "json",
async: false,
data: JSON.stringify({"objSearch": JSON.stringify(objSearch) }),
success: function (data) {});