Pasar una matriz a de servicio de WCF a través de CONSEGUIR

Tengo una llamada AJAX que quiero correr contra un WCF OBTENER el servicio. Básicamente, la llamada al servicio (a través de jquery) se parece a esto:

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

Cuando esta llamada se ejecuta, veo el ponerse en firebug ir a través correctamente, y yo le pego a la estación. Sin embargo, el parámetro statusTypes siempre es null.

El hacerse de jquery parece que está codificado, pero cuando no me codificar los soportes, la llamada no va a entrar en la estación todos:

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

Y el servicio WCF en sí:

[OperationContract]

[Atributos webinvoke(Method= «GET», BodyStyle = WebMessageBodyStyle.WrappedRequest,
ResponseFormat =
WebMessageFormat.Json)]

público
ResultsViewModel
GetTags(string query, int[]
statusTypes)

Es posible pasar una matriz a través de LLEGAR a un servicio WCF?

Las permutaciones no son numerosos, así que podría escribir un individuo extremo «por matriz», pero prefiero mantenerlo en uno.

Como solución alternativa, se puede convertir la matriz en una cadena y, a continuación, analizar en su servicio mediante Cadena.Split().

OriginalEl autor ddango | 2011-06-22

2 Kommentare

  1. 10

    Es posible, pero no con el fuera-de-la-caja de WCF. Con el «jQuery apoyo» en la WCF codeplex página, usted puede recibir todos los datos enviados por jQuery (incluyendo matrices, objetos anidados, etc) en una variable sin tipo, tanto en el cuerpo (para las solicitudes POST) y en la cadena de consulta (para OBTENER). La asignación entre jQuery variables de matriz (cuyos nombres contienen ‘[‘ y ‘]’) y los parámetros de la operación no puede ser realizada en WCF 4.0 (al menos no sin escribir un mensaje en el formateador).

    Esto debería ser más simple, sin embargo, en la nueva Web de WCF Api (también disponible en el sitio de codeplex).

    Actualización: este es un ejemplo de un formateador que trabaja para su escenario:

    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();
        }
    }
    ¿Cómo registrar el comportamiento personalizado de la clase a través de la aplicación.config en lugar de código?
    Encuentra la respuesta a mí mismo – necesidad de volver de un comportamiento personalizado de extensión: codeproject.com/Articles/37156/… y añadir que el comportamiento de extensiones en la web.config

    OriginalEl autor carlosfigueira

  2. 2

    No, no es posible. Usted no puede asignar la matriz de valores de URL para el parámetro. Si desea pasar de la matriz de uso de HTTP POST.

    Usted realmente puede (ver respuesta), no es fácil de hacer.
    Sí veo. Muy bonita respuesta y un montón de trabajo para hacer que funcione. Mi respuesta fue más específico a lo actual UriTemplate apoyo fuera de la caja. No pensaba en la extensión. También puede capturar en raw solicitud como una secuencia y tratar de extraer de la cadena de consulta.

    OriginalEl autor Ladislav Mrnka

Kommentieren Sie den Artikel

Bitte geben Sie Ihren Kommentar ein!
Bitte geben Sie hier Ihren Namen ein

Pruebas en línea