在一个较大的项目中,我很难获得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<Player> 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<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(); } }
调用前三个方法中的任何一个都可以正常工作(但没有参数,您会注意到)。使用此客户端代码调用最后一个方法(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消息为“预期状态为’元素’..遇到名称为”,名称空间为”的’文本’。’。
我尝试发送JSON的未包装版本…
{“名称”:“ Simon”,“得分”:“ 100”,“俱乐部”:“里格比”}
但在服务中,该参数为null,并且没有格式程序异常。
这是服务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>
这是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; } } }
非常感谢任何帮助,如果需要任何其他信息,请告诉我。
非常感谢。
您以错误的方式player对方法的输入参数进行编码TotalScore。
player
TotalScore
我建议您使用json2.js中的JSON.stringify函数将任何JavaScript对象转换为JSON。
JSON.stringify
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"); } });
如果BodyStyle = WebMessageBodyStyle.Wrapped将TotalScore方法的属性BodyStyle = WebMessageBodyStyle.WrappedRequest更改为alert(data.TotalScoreResult),则可以将success句柄中的更改为alert(data)。
BodyStyle = WebMessageBodyStyle.Wrapped
BodyStyle = WebMessageBodyStyle.WrappedRequest
alert(data.TotalScoreResult)
success
alert(data)