通过GET将数组传递给WCF服务

我有一个AJAX调用,我想针对WCF GET服务运行。 基本上,对服务的调用(通过jquery)看起来像这样:

$.get(serviceEndpoint, {query : "some search text", statusTypes: [1, 2]}, function (result) { /* do something*/ }, 'text'); 

当这个调用运行时,我看到firebug中的GET正确通过,我确实击中了端点。 但是,参数statusTypes始终为null。

来自jquery的GET本身看起来像是编码的,但是当我不对括号进行编码时,调用根本不会进入端点:

HTTP://localhost/Services/SomeService.svc/Endpoint statusTypes%5B%5D = 1&statusTypes%5B%5D = 2&查询=一些+搜索+文本

而WCF服务本身:

[OperationContract的]

[WebInvoke(Method =“GET”,BodyStyle = WebMessageBodyStyle.WrappedRequest,
ResponseFormat = WebMessageFormat.Json)]

public ResultsViewModel GetTags(string query,int [] statusTypes)

是否可以通过GET将数组传递给WCF服务?

排列并不多,所以我可以编写一个单独的端点“每个数组”,但我宁愿把它保持在一个。

这是可能的,但不是开箱即用的WCF。 通过WCF codeplex页面中的“jQuery支持”,您可以接收jQuery(包括数组,嵌套对象等)在非类型变量中发送的所有数据,包括正文(用于POST请求)和查询字符串(对于GET)。 jQuery数组变量(其名称包含'[‘和’]’)和操作参数之间的映射无法在WCF 4.0中完成(至少在没有编写消息格式化程序的情况下)。

但是,对于新的WCF Web API(也可在codeplex站点上提供),这应该更简单。

更新 :这是适用于您的场景的格式化程序的示例:

 public class StackOverflow_6445171 { [ServiceContract] public class Service { [WebGet(ResponseFormat = WebMessageFormat.Json)] public string GetLabelPacketTags(string query, int[] statusTypes) { StringBuilder sb = new StringBuilder(); sb.Append("Query=" + query); sb.Append(", statusTypes="); if (statusTypes == null) { sb.Append("null"); } else { sb.Append("["); for (int i = 0; i < statusTypes.Length; i++) { if (i > 0) sb.Append(","); sb.Append(statusTypes[i]); } sb.Append("]"); } return sb.ToString(); } } class MyWebHttpBehavior : WebHttpBehavior { protected override IDispatchMessageFormatter GetRequestDispatchFormatter(OperationDescription operationDescription, ServiceEndpoint endpoint) { return new MyArrayAwareFormatter(operationDescription, this.GetQueryStringConverter(operationDescription)); } class MyArrayAwareFormatter : IDispatchMessageFormatter { OperationDescription operation; QueryStringConverter queryStringConverter; public MyArrayAwareFormatter(OperationDescription operation, QueryStringConverter queryStringConverter) { this.operation = operation; this.queryStringConverter = queryStringConverter; } public void DeserializeRequest(Message message, object[] parameters) { if (message.Properties.ContainsKey("UriMatched") && (bool)message.Properties["UriMatched"]) { UriTemplateMatch match = message.Properties["UriTemplateMatchResults"] as UriTemplateMatch; NameValueCollection queryValues = match.QueryParameters; foreach (MessagePartDescription parameterDescr in this.operation.Messages[0].Body.Parts) { string parameterName = parameterDescr.Name; int index = parameterDescr.Index; if (parameterDescr.Type.IsArray) { Type elementType = parameterDescr.Type.GetElementType(); string[] values = queryValues.GetValues(parameterName + "[]"); Array array = Array.CreateInstance(elementType, values.Length); for (int i = 0; i < values.Length; i++) { array.SetValue(this.queryStringConverter.ConvertStringToValue(values[i], elementType), i); } parameters[index] = array; } else { parameters[index] = this.queryStringConverter.ConvertStringToValue(queryValues.GetValues(parameterName)[0], parameterDescr.Type); } } } } public Message SerializeReply(MessageVersion messageVersion, object[] parameters, object result) { throw new NotSupportedException("This is a request-only formatter"); } } } public static void Test() { string baseAddress = "http://" + Environment.MachineName + ":8000/Service"; ServiceHost host = new ServiceHost(typeof(Service), new Uri(baseAddress)); host.AddServiceEndpoint(typeof(Service), new WebHttpBinding(), "").Behaviors.Add(new MyWebHttpBehavior()); host.Open(); Console.WriteLine("Host opened"); WebClient c = new WebClient(); Console.WriteLine(c.DownloadString(baseAddress + "/GetLabelPacketTags?query=some+text&statusTypes[]=1&statusTypes[]=2")); Console.WriteLine(c.DownloadString(baseAddress + "/GetLabelPacketTags?query=some+text&statusTypes%5B%5D=1&statusTypes%5B%5D=2")); Console.Write("Press ENTER to close the host"); Console.ReadLine(); host.Close(); } } 

不,这是不可能的。 您无法将值数组从URL映射到参数。 如果要传递数组,请使用HTTP POST。