在WCF服务方法中使用JSON

在较大的项目中,我无法获取WCF服务方法来使用JSON参数。 所以我制作了一个较小的测试用例,并且回应了行为。 如果我调试服务,我可以看到服务调用时参数值为null。 Fiddler确认JSON正在发送,JsonLint确认它是有效的。

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

[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 GetPlayers(); [OperationContract] [WebInvoke( Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped, ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json, UriTemplate = "totalscore")] string TotalScore(Player player); } 

……及其实施

 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 GetPlayers() { return new List() { 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(); } } 

调用前三种方法中的任何一种都可以正常工作(但是没有参数,你会注意到)。 使用此客户端代码调用最后一个方法(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"); } }); } 

… 结果是 …

尝试反序列化参数http://tempuri.org/:player时出错。 InnerException消息是’Expecting state’Element’..遇到’Text’,名称为”,namespace”。 ”。

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

{ “名称”: “西蒙”, “分数”: “100”, “俱乐部”: “格比”}

但在服务中,参数为null,并且没有格式化程序exception。

这是服务web.config的system.serviceModel分支:

                     

这是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; } } } 

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

非常感谢。

您以错误的方式编码方法TotalScore的输入参数player

我建议你使用JSON.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"); } }); 

如果将TotalScore方法的BodyStyle = WebMessageBodyStyle.Wrapped属性更改为BodyStyle = WebMessageBodyStyle.Wrapped ,则可以将success句柄中的alert(data.TotalScoreResult)更改为alert(data)

您没有在Web调用上sepcified Method参数。 请参阅: http : //msdn.microsoft.com/en-us/library/bb472541(v = vs.90).aspx

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

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

希望这有帮助!