2011-03-31 111 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