在WCF服务方法中使用JSON

时间:2021-06-09 09:53:54

In a larger project I am having trouble getting a WCF service method to consume a JSON parameter. So I produced a smaller test case and the behaviour is echoed. If I debug the service I can see the parameter value is null at the service call. Fiddler confirms that the JSON is being sent and JsonLint confirms it is valid.

在一个较大的项目中,我在使用JSON参数的WCF服务方法时遇到了麻烦。因此,我制作了一个较小的测试用例,并且这种行为得到了响应。如果我调试服务,我可以在服务调用中看到参数值为null。Fiddler确认正在发送JSON, JsonLint确认它是有效的。

Code below with annotations from debugging.

下面的代码带有来自调试的注释。

[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);

}

... and its implementation

…及其实现

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

Calling any of the first three methods works correctly (but no parameters as you'll note). Calling the last method (TotalScore) with this client code ...

调用前三个方法中的任何一个都可以正常工作(但是您将注意到没有参数)。使用此客户端代码调用最后一个方法(TotalScore)…

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

... results in ...

…导致……

There was an error while trying to deserialize parameter http://tempuri.org/:player. The InnerException message was 'Expecting state 'Element'.. Encountered 'Text' with name '', namespace ''. '.

在尝试反序列化参数http://tempuri.org/:player时发生了错误。InnerException消息是“预期状态”元素。遇到“Text”和“name”、“namespace”。”。

I have tried sending an unwrapped version of the JSON ...

我尝试过发送一个未包装的JSON版本…

{"Name":"Simon","Score":"100","Club":"Rigby"}

{ " Name ":“西蒙”、“分数”:“100”,“俱乐部”:“Rigby”}

but at the service the parameter is null, and no formatter exceptions.

但在服务中,参数为null,没有格式化程序异常。

This is the system.serviceModel branch of the service web.config:

这是系统。service web的serviceModel分支。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>

And here is the Player 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; } }

    }

Any help greatly appreciated and if any other info is required, please let me know.

非常感谢您的帮助,如果需要其他信息,请告诉我。

Many thanks.

多谢。

3 个解决方案

#1


10  

You encode the input parameter player of the method TotalScore in the wrong way.

您以错误的方式对方法TotalScore的输入参数播放器进行编码。

I recommend you to use JSON.stringify function from json2.js to convert any JavaScript objects to JSON.

我建议您使用JSON。从json2 stringify函数。将任何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");
    }
});

If you change the BodyStyle = WebMessageBodyStyle.Wrapped attribute of the TotalScore method to BodyStyle = WebMessageBodyStyle.WrappedRequest you can change the alert(data.TotalScoreResult) in the success handle to alert(data).

如果你改变了BodyStyle = WebMessageBodyStyle。TotalScore方法的包装属性为BodyStyle = WebMessageBodyStyle。WrappedRequest命令可以在成功句柄中更改alert(data. totalscoreresult)以警告(data)。

#2


0  

You have not sepcified the Method parameter on web invoke. See: http://msdn.microsoft.com/en-us/library/bb472541(v=vs.90).aspx

您还没有对web调用的方法参数进行验证。参见:http://msdn.microsoft.com/en-us/library/bb472541(v =应用程序). aspx

#3


0  

I got the same problems (405 methods not allowed) using WCF POST JSON data. I found on this article below

我使用WCF POST JSON数据得到了相同的问题(不允许使用405种方法)。我在下面这篇文章中找到的

http://blog.weareon.net/calling-wcf-rest-service-from-jquery-causes-405-method-not-allowed/

http://blog.weareon.net/calling - wcf -休息-服务-从jquery -原因- 405——不——allowed/方法

Hope this help!

希望这次的帮助!

#1


10  

You encode the input parameter player of the method TotalScore in the wrong way.

您以错误的方式对方法TotalScore的输入参数播放器进行编码。

I recommend you to use JSON.stringify function from json2.js to convert any JavaScript objects to JSON.

我建议您使用JSON。从json2 stringify函数。将任何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");
    }
});

If you change the BodyStyle = WebMessageBodyStyle.Wrapped attribute of the TotalScore method to BodyStyle = WebMessageBodyStyle.WrappedRequest you can change the alert(data.TotalScoreResult) in the success handle to alert(data).

如果你改变了BodyStyle = WebMessageBodyStyle。TotalScore方法的包装属性为BodyStyle = WebMessageBodyStyle。WrappedRequest命令可以在成功句柄中更改alert(data. totalscoreresult)以警告(data)。

#2


0  

You have not sepcified the Method parameter on web invoke. See: http://msdn.microsoft.com/en-us/library/bb472541(v=vs.90).aspx

您还没有对web调用的方法参数进行验证。参见:http://msdn.microsoft.com/en-us/library/bb472541(v =应用程序). aspx

#3


0  

I got the same problems (405 methods not allowed) using WCF POST JSON data. I found on this article below

我使用WCF POST JSON数据得到了相同的问题(不允许使用405种方法)。我在下面这篇文章中找到的

http://blog.weareon.net/calling-wcf-rest-service-from-jquery-causes-405-method-not-allowed/

http://blog.weareon.net/calling - wcf -休息-服务-从jquery -原因- 405——不——allowed/方法

Hope this help!

希望这次的帮助!