En un proyecto más grande, estoy teniendo problemas para conseguir un servicio de WCF método para consumir un JSON parámetro. Así que me produce una menor de casos de prueba y el comportamiento se repite. Si me depurar el servicio puedo ver el valor del parámetro es null en la llamada de servicio. El violinista confirma que el JSON que está siendo enviado y JsonLint confirma es válido.

Código de abajo con anotaciones de depuración.

[ServiceContract]
public interface IWCFService
{

    [OperationContract]
    [WebInvoke(BodyStyle = WebMessageBodyStyle.WrappedRequest,
            ResponseFormat = WebMessageFormat.Json,
            UriTemplate = "getstring")]

    string GetString();

    [OperationContract]
    [WebInvoke(BodyStyle = WebMessageBodyStyle.WrappedRequest,
        ResponseFormat = WebMessageFormat.Json,
        UriTemplate = "getplayer")]
    //[WebGet(BodyStyle = WebMessageBodyStyle.WrappedRequest,
    //   ResponseFormat = WebMessageFormat.Json,
    //   UriTemplate = "getplayers")]
    Player GetPlayer();

    [OperationContract]
    [WebInvoke(BodyStyle = WebMessageBodyStyle.WrappedRequest,
        ResponseFormat = WebMessageFormat.Json,
        UriTemplate = "getplayers")]
    List<Player> GetPlayers();

    [OperationContract]
    [WebInvoke(
        Method = "POST",
        BodyStyle = WebMessageBodyStyle.Wrapped,
        ResponseFormat = WebMessageFormat.Json,
        RequestFormat = WebMessageFormat.Json,
        UriTemplate = "totalscore")]
    string TotalScore(Player player);

}

… y su aplicación

public class WCFService : IWCFService
{
    public string GetString()
    {
        return "hello from GetString";
    }

    public Player GetPlayer()
    {
        return new Player()
                {
                    Name = "Simon", 
                    Score = 1000, 
                    Club = new Club()
                            {
                                Name = "Tigers", 
                                Town = "Glenelg"
                            }
                };
    }

    public List<Player> GetPlayers()
    {
        return new List<Player>()
            {
                new Player()
                    {
                        Name = "Simon", 
                        Score = 1000 , 
                        Club=new Club()
                                {
                                    Name="Tigers", 
                                    Town = "Glenelg"
                                }
                    }, 
                new Player()
                    {
                        Name = "Fred", Score = 50,
                        Club=new Club()
                                {
                                    Name="Blues",
                                    Town="Sturt"
                                }
                    }
            };
    }

    public string TotalScore(Player player)
    {
        return player.Score.ToString();
    }
}

Llamar a cualquiera de los tres primeros métodos funciona correctamente (pero no a los parámetros como se le nota). Llamar al último método (TotalScore) con este código de cliente …

function SendPlayerForTotal() {
        var json = '{ "player":{"Name":"' + $("#Name").val() + '"'
            + ',"Score":"' + $("#Score").val() + '"'
            + ',"Club":"' + $("#Club").val() + '"}}';

        $.ajax(
        {
            type: "POST",
            contentType: "application/json; charset=utf-8",
            url: "http://localhost/wcfservice/wcfservice.svc/json/TotalScore",
            data: json,
            dataType: "json",
            success: function (data) { alert(data); },
            error: function () { alert("Not Done"); }
        });
    }

… resultados en …

Hubo un error al intentar deserializar parámetro http://tempuri.org/:player. El InnerException mensaje fue » Esperando que el estado ‘Elemento’.. Encontrados «Texto» con el nombre de » espacio de nombres «. ‘.

He intentado enviar un envueltos versión del JSON …

{«Nombre»:»Simón», La»Puntuación»:»100″,»Club»:»Rigby»}

pero en el servicio que el parámetro es null, y no formateador de excepciones.

Este es el sistema.serviceModel rama de la web del servicio.config:

<system.serviceModel>
<services>
    <service name="WCFService.WCFService" behaviorConfiguration="WCFService.DefaultBehavior">
        <endpoint address="json" binding="webHttpBinding" contract="WCFService.IWCFService" behaviorConfiguration="jsonBehavior"/>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
    </service>
</services>

<behaviors>
    <serviceBehaviors>
        <behavior name="WCFService.DefaultBehavior">
            <serviceMetadata httpGetEnabled="true"/>
            <serviceDebug includeExceptionDetailInFaults="true"/>
        </behavior>
    </serviceBehaviors>

    <endpointBehaviors>
        <behavior name="jsonBehavior">
            <webHttp/>
        </behavior>             
    </endpointBehaviors>
</behaviors>

Y aquí está el Jugador DataContract.

[DataContract(Name = "Player")]
    public class Player
    {
        private string _name;
        private int _score;
        private Club _club;

        [DataMember]
        public string Name { get { return _name; } set { _name = value; } }

        [DataMember]
        public int Score { get { return _score; } set { _score = value; } }

        [DataMember]
        public Club Club { get { return _club; } set { _club = value; } }

    }

Cualquier ayuda muy apreciada y si cualquier otra información es necesaria, por favor hágamelo saber.

Muchas gracias.

OriginalEl autor Simon Rigby | 2011-03-31

3 Comentarios

  1. 10

    Codificar el parámetro de entrada player del método TotalScore en el camino equivocado.

    Te recomiendo usar JSON.stringify función de json2.js para convertir todo tipo de objetos JavaScript JSON.

    var myPlayer = {
        Name: "Simon",
        Score: 1000,
        Club: {
            Name: "Tigers",
            Town: "Glenelg"
        }
    };
    $.ajax({
        type: "POST",
        url: "/wcfservice/wcfservice.svc/json/TotalScore",
        data: JSON.stringify({player:myPlayer}), //for BodyStyle equal to 
                                                 //WebMessageBodyStyle.Wrapped or 
                                                 //WebMessageBodyStyle.WrappedRequest
        //data: JSON.stringify(myPlayer), //for no BodyStyle attribute
                                           //or WebMessageBodyStyle.WrappedResponse
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        success: function(data, textStatus, xhr) {
            alert(data.TotalScoreResult); //for BodyStyle = WebMessageBodyStyle.Wrapped
                                          //or WebMessageBodyStyle.WrappedResponse
            //alert(data); //for BodyStyle = WebMessageBodyStyle.WrappedRequest
                            //or for no BodyStyle attributes
        },
        error: function (xhr, textStatus, ex) {
            alert("Not Done");
        }
    });

    Si cambia el BodyStyle = WebMessageBodyStyle.Wrapped atributo de la TotalScore método para BodyStyle = WebMessageBodyStyle.WrappedRequest puede cambiar el alert(data.TotalScoreResult) en el success manejar a alert(data).

    Muchas gracias … ese era el problema. Mirando el JSON en fiddler, veo que el valor de int no es citado. Yo estaba bajo la impresión de que deberían ser. Muchas Gracias.
    Rigby: Sí, fue uno de los errores. El Club propiedad que serializado también en la «Forma» de estilo que también están mal. He modificado mi respuesta, además de mostrar el sentido de BodyStyle atributo. Espero que también te será de ayuda.
    Muchas gracias. ¿Cómo stringify ir con las fechas. Mi servicio WCF se tropiece con ellos, ya que no tiene el /fecha() envoltorio a su alrededor. Es que algo que me gustaría necesidad de abordar por separado. No estoy seguro de cómo me había gancho en el que el objeto json que había en una llamada. Espero que tenga sentido.
    Rigby: DateTime o Date son no tipo estándar, que es apoyado por JSON. Así que usted debe hacer algunas de conversión adicionales en el lado del cliente (JavaScript) o en el lado del servidor. Qué necesita para convertir la fecha de publicación del servidor al cliente o post la JqvqScript Date al servidor para ser fácil convertir a DateTime? Yo podría publicar algunos ejemplos o, probablemente, este post resolver tú problema.
    Muchas gracias, que terminó con una variación de Rick Strahl del Servicio de Proxy que utiliza JSON2 stringify(). Gracias por toda su ayuda. 🙂

    OriginalEl autor Oleg

Dejar respuesta

Please enter your comment!
Please enter your name here