Передача массива в службу WCF через GET - PullRequest
10 голосов
/ 22 июня 2011

У меня есть вызов AJAX, который я хочу запустить для службы WCF GET.По сути, вызов службы (через jquery) выглядит следующим образом:

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

Когда этот вызов запускается, я вижу, что GET в firebug проходит правильно, и я достигаю конечной точки.Однако параметр statusTypes всегда равен нулю.

Сам GET из jquery выглядит так, как будто он закодирован, но когда я не закодирую скобки, вызов вообще не будет входить в конечную точку:

http://localhost/Services/SomeService.svc/Endpoint?statusTypes%5B%5D=1&statusTypes%5B%5D=2&query=some+search+text

И сама служба WCF:

[OperationContract]

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

public ResultsViewModel GetTags (строковый запрос, int [] statusTypes)

Возможно липередать массив через GET в службу WCF?

Перестановок немного, поэтому я мог бы написать отдельную конечную точку "для каждого массива", но я бы предпочел оставить ее в одной.

Ответы [ 2 ]

10 голосов
/ 22 июня 2011

Это возможно, но не с готовым WCF.С помощью «поддержки jQuery» на странице кодового сплетения WCF вы можете получать все данные, отправленные jQuery (включая массивы, вложенные объекты и т. Д.) В нетипизированной переменной, как в теле (для запросов POST) и в строке запроса (для GET).Сопоставление между переменными массива jQuery (имена которых содержат '[' и ']') и параметрами операций невозможно выполнить в WCF 4.0 (по крайней мере, без написания средства форматирования сообщений).

Однако это должно быть проще, на новых веб-API WCF (также доступно на сайте 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();
    }
}
2 голосов
/ 22 июня 2011

Нет, это невозможно.Вы не можете отобразить массив значений из URL в параметр.Если вы хотите передать массив, используйте HTTP POST.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...