2011-03-31 90 views
8

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

下面的代码与调试注释。

[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消息是'Expecting state'Element'..遇到'Text',名字为'',namespace''。 ”。

我试图发送JSON的展开的版本...

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

但在服务的参数是空的,没有格式化程序异常。

这是服务的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> 

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

    } 

任何帮助非常感谢,如果任何其他信息是必需的,请让我知道。

非常感谢。

回答

10

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

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

如果你改变了TotalScore方法的BodyStyle = WebMessageBodyStyle.Wrapped属性BodyStyle = WebMessageBodyStyle.WrappedRequest您可以在success手柄改变alert(data.TotalScoreResult)alert(data)

+1

非常感谢你..这是问题所在。看着小提琴手中的JSON,我看到int值没有被引用。我的印象是他们应该是。非常感谢。 – 2011-03-31 10:47:39

+0

@Simon Rigby:是的,这是错误之一。您也以“表格”样式序列化的“俱乐部”属性也是错误的。我修改了我的答案,以显示'BodyStyle'属性的含义。我希望它也能帮助你。 – Oleg 2011-03-31 10:49:59

+0

非常感谢。字符串化如何随日期一起进行。我的WCF服务正在绊倒他们,因为它没有/ date()包装器。这是我需要单独解决的问题。我不确定如何在一次调用中将对象添加到该对象中。我希望那会让人神往。 – 2011-03-31 14:36:15