简体   繁体   English

在WCF服务方法中使用JSON

[英]Consuming JSON in WCF service method

In a larger project I am having trouble getting a WCF service method to consume a JSON parameter. 在一个更大的项目中,我无法获得WCF服务方法来使用JSON参数。 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. 如果我调试服务,我可以看到服务调用时参数值为null。 Fiddler confirms that the JSON is being sent and JsonLint confirms it is valid. 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 . 尝试反序列化参数http://tempuri.org/:player时出错。 The InnerException message was 'Expecting state 'Element'.. Encountered 'Text' with name '', namespace ''. InnerException消息是'Expecting state'Element'..遇到名为'',namespace''的'Text'。 '. ”。

I have tried sending an unwrapped version of the JSON ... 我试过发送一个未包装的JSON版本......

{"Name":"Simon","Score":"100","Club":"Rigby"} { “名称”: “西蒙”, “分数”: “100”, “俱乐部”: “格比”}

but at the service the parameter is null, and no formatter exceptions. 但在服务中,参数为null,并且没有格式化程序异常。

This is the system.serviceModel branch of the service web.config: 这是服务web.config的system.serviceModel分支:

<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. 这是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. 非常感谢。

You encode the input parameter player of the method TotalScore in the wrong way. 您以错误的方式编码方法TotalScore的输入参数player

I recommend you to use JSON.stringify function from json2.js to convert any JavaScript objects to JSON. 我建议你使用JSON.stringify函数从json2.js到任何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.Wrapped的属性TotalScore方法BodyStyle = WebMessageBodyStyle.WrappedRequest可以更改alert(data.TotalScoreResult)success把手alert(data)

I got the same problems (405 methods not allowed) using WCF POST JSON data. 我使用WCF POST JSON数据得到了同样的问题(不允许405个方法)。 I found on this article below 我在下面的这篇文章中找到了

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

Hope this help! 希望这有帮助!

You have not sepcified the Method parameter on web invoke. 您没有在Web调用上sepcified Method参数。 See: http://msdn.microsoft.com/en-us/library/bb472541(v=vs.90).aspx 请参阅: http//msdn.microsoft.com/en-us/library/bb472541(v = vs。90).aspx

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM