2011-03-31 18 views
8

Daha büyük bir projede, bir JSON parametresini tüketmek için bir WCF hizmet yönteminin kullanılmasında sorun yaşıyorum. Bu yüzden daha küçük bir test vakası ürettim ve davranış yankılandı. Hizmetin hata ayıklaması durumunda, parametre değerinin servis çağrısında null olduğunu görebiliyorum. Fiddler JSON'un gönderildiğini ve JsonLint'in geçerli olduğunu doğruladı.WCF hizmet yönteminde JSON tüketim

Aşağıdaki kod hata ayıklamadan ek açıklamalarla birlikte. İlk üç yöntemlerden herhangi çağrılması

[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); 

} 

... ve uygulaması

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(); 
    } 
} 

düzgün çalışır (ama senin kadar hiçbir parametre dikkat edeceğiz). parametresini http://tempuri.org/:player serisini çalışırken ... Bu istemci kodu ile son yöntem (TotalScore) çağrılması

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"); } 
     }); 
    } 

... lütfen ...

sonuç bir hata oluştu. InnerException iletisinde 'Durum Bekleniyor' Öğesi '..' Metin 'ile' ', ad alanı' 'ile karşılaşıldı. '.

Ben JSON bir Çizelgesi sürümünü gönderme denedi ...

{ "Ad": "Simon", "Skor": "100", "Kulüp": "Rigby"}

ancak hizmette parametre boş ve biçimlendirici istisnası yok. Burada

Ve

<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> 
Oyuncu DataContract geçerli:

Bu hizmet web.config System.ServiceModel dalıdır.

[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; } } 

    } 

Herhangi bir yardım için teşekkür ederiz ve başka bilgi gerekiyorsa lütfen bana bildirin.

Çok teşekkürler.

cevap

10

TotalScore yönteminin player giriş parametresini yanlış şekilde kodlarsınız.

Herhangi bir JavaScript nesnesini JSON'a dönüştürmek için json2.js numaralı JSON.stringify işlevini kullanmanızı öneririz. Eğer BodyStyle = WebMessageBodyStyle.WrappedRequest için TotalScore yöntemin BodyStyle = WebMessageBodyStyle.Wrapped niteliğini değiştirirseniz

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"); 
    } 
}); 

Eğer alert(data) için success sapı alert(data.TotalScoreResult) değiştirebilirsiniz.

+1

Çok teşekkür ederim .. sorun buydu. Fiddler'da JSON'a baktığımda, int değerinin aktarılmadığını görüyorum. Olması gerektiği izlenimi altındaydım. Çok teşekkürler. –

+0

@Simon Rigby: Evet, hatalardan biriydi. Aynı zamanda "Form" tarzında da seri hale getirdiğiniz 'Club' özelliği de yanlıştır. Ben de 'BodyStyle' özniteliğinin anlamını göstermek için cevabımı değiştirdim. Umarım aynı zamanda size yardımcı olacaktır. – Oleg

+0

Çok teşekkürler. Çekilmek nasıl tarihlerle gider. WCF servisim, üzerlerinde/date() sarmalayıcı bulunmadığı için üzerlerine düşüyor. Ayrı ayrı ele almam gereken bir şey mi? Bir çağrıda jsonun nesnesi olarak buna nasıl bağlanacağından emin değilim. Umarım bu sene yapar. –