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

C# 通过GET将数组传递给WCF服务,c#,wcf,jquery,C#,Wcf,Jquery,我有一个AJAX调用,我想针对WCF GET服务运行该调用。基本上,对服务的调用(通过jquery)如下所示: $.get(serviceEndpoint, {query : "some search text", statusTypes: [1, 2]}, function (result) { /* do something*/ }, 'text'); 当这个调用运行时,我看到GET-in-firebug正确通过,并且我确实到达了端点。但是,参数statusTypes始终为空 从jquer

我有一个AJAX调用,我想针对WCF GET服务运行该调用。基本上,对服务的调用(通过jquery)如下所示:

$.get(serviceEndpoint, {query : "some search text", statusTypes: [1, 2]}, function (result) { /* do something*/ }, 'text');
当这个调用运行时,我看到GET-in-firebug正确通过,并且我确实到达了端点。但是,参数
statusTypes
始终为空

从jquery获取本身看起来像是经过编码的,但是如果我没有对括号进行编码,调用将根本不会进入端点:

以及WCF服务本身:

[经营合同]

[WebInvoke(Method=“GET”,BodyStyle=WebMessageBodyStyle.WrappedRequest,
响应格式= WebMessageFormat.Json)]

公开的 结果视图模型 GetTags(字符串查询,int[] 状态(类型)

是否可以通过GET将阵列传递给WCF服务


排列不是很多,所以我可以“每个数组”编写一个单独的端点,但我宁愿将其保存在一个端点中。

不,这是不可能的。无法将值数组从URL映射到参数。如果您想传递数组,可以使用HTTPPOST。

这是可能的,但不能使用现成的WCF。使用中的“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();
    }
}
公共类堆栈溢出\u 6445171
{
[服务合同]
公务舱服务
{
[WebGet(ResponseFormat=WebMessageFormat.Json)]
公共字符串GetLabelPacketTags(字符串查询,int[]状态类型)
{
StringBuilder sb=新的StringBuilder();
sb.追加(“Query=”+Query);
sb.追加(“,statusTypes=”);
if(statusTypes==null)
{
某人附加(“空”);
}
其他的
{
某人加上(“[”);
for(int i=0;i0)sb.追加(“,”);
sb.追加(状态类型[i]);
}
某人加上(“]”);
}
使某人返回字符串();
}
}
类MyWebHttpBehavior:WebHttpBehavior
{
受保护的重写IDispatchMessageFormatter GetRequestDispatchFormatter(OperationDescription OperationDescription,ServiceEndpoint)
{
返回新的MyArrayWareFormatter(operationDescription,this.GetQueryStringConverter(operationDescription));
}
MyArrayWareFormatter类:IDispatchMessageFormatter
{
操作描述操作;
QueryStringConverter QueryStringConverter;
公共MyArrayWareformter(操作说明操作,QueryStringConverter QueryStringConverter)
{
这个操作=操作;
this.queryStringConverter=queryStringConverter;
}
public void反序列化请求(消息,对象[]参数)
{
if(message.Properties.ContainsKey(“UriMatched”)&&(bool)message.Properties[“UriMatched”])
{
UriTemplateMatch=message.Properties[“UriTemplateMatchResults”]作为UriTemplateMatch;
NameValueCollection queryValues=match.QueryParameters;
foreach(此.operation.Messages[0].Body.Parts中的MessagePartDescription参数descr)
{
字符串parameterName=parameterDescr.Name;
int index=参数描述索引;
if(参数描述类型IsArray)
{
Type elementType=parameterDescr.Type.GetElementType();
string[]values=queryValues.GetValues(parameterName+“[]”);
Array Array=Array.CreateInstance(elementType,values.Length);
for(int i=0;i