通过GET将数组传递给WCF服务 [英] Passing an array to WCF service via GET

查看:133
本文介绍了通过GET将数组传递给WCF服务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有,我想对一个WCF得到服务运行AJAX调用。基本上,调用服务(通过jQuery)看起来是这样的:

I have an AJAX call that I want to run against a WCF GET service. Basically, the call to the service (via jquery) looks like this:

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

在此呼叫会跑,我看到萤火虫的GET经过正确的,我做打端点。然而,参数 statusTypes 总是空。

When this call gets run, I see the GET in firebug go through correctly, and I do hit the endpoint. However, the parameter statusTypes is always null.

获取自己从jQuery的看起来是编码的,但是当我不编码的支架,电话根本不会进入端点:

The GET itself from jquery looks like it is encoded, but when I don't encode the brackets, the call won't enter the endpoint at all:

HTTP:?//localhost/Services/SomeService.svc/Endpoint statusTypes %5B%5D = 1&安培; statusTypes%5B%5D = 2及查询=某些+搜索+文字

和WCF服务本身:

[OperationContract的]

[OperationContract]

[WebInvoke(方法= GET,BodyStyle = WebMessageBodyStyle.WrappedRequest,结果
ResponseFormat =
WebMessageFormat.Json)

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

公共
$ ResultsViewModel b $ b GetTags(查询字符串,INT []
statusTypes)

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

是否有可能通过GET传递一个数组WCF服务?

Is it possible to pass an array via GET to a WCF service?

的排列并不多,所以我可以写每个阵列的个人终端,但我宁愿保持它在其中。

The permutations aren't numerous, so I could write an individual endpoint "per array", but I'd rather keep it in one.

推荐答案

这是可能的,但不与外的现成的WCF。随着jQuery的支持,在 WCF CodePlex网站页面,就可以接收所有的jQuery发送的数据(包括数组,嵌套对象等)在一个无类型变量,无论是在身体上(POST请求),并在查询字符串(GET)。 jQuery的数组变量之间的映射(其名称中包含[和])和运行参数不能在WCF 4.0来完成(至少在没有写消息格式)。

It is possible, but not with the out-of-the-box WCF. With the "jQuery support" in the WCF codeplex page, you can receive all of the data sent by jQuery (including arrays, nested objects, etc) in an untyped variable, both on the body (for POST requests) and on the query string (for GET). The mapping between jQuery array variables (whose names contain '[' and ']') and operation parameters cannot be done in WCF 4.0 (at least not without writing a message formatter).

这应该是简单的,但是,在新的WCF的Web的API(也可在CodePlex上网站)

This should be simpler, however, on the new WCF Web APIs (also available on the codeplex site).

更新:这是适用于您的方案格式化的例子:

Update: this is an example of a formatter which works for your scenario:

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();
    }
}

这篇关于通过GET将数组传递给WCF服务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆