WCF Hizmetinden temiz JSON'u nasıl iade edebilirim?


233

WCF hizmetinden bazı JSON döndürmeye çalışıyorum. Bu hizmet veritabanımdaki bazı içeriği döndürüyor. Verileri alabilirim. Ancak, JSON'umun biçimi hakkında endişeliyim. Şu anda, döndürülen JSON şu şekilde biçimlendirilmiştir:

{"d":"[{\"Age\":35,\"FirstName\":\"Peyton\",\"LastName\":\"Manning\"},{\"Age\":31,\"FirstName\":\"Drew\",\"LastName\":\"Brees\"},{\"Age\":29,\"FirstName\":\"Tony\",\"LastName\":\"Romo\"}]"} 

Gerçekte, JSON'umun olabildiğince temiz biçimlendirilmesini istiyorum. Ben (yanlış olabilir), temiz JSON temsil sonuçları aynı koleksiyon, şöyle görünmesi gerektiğine inanıyorum:

[{
  "Age": 35,
  "FirstName": "Peyton",
  "LastName": "Manning"
}, {
  "Age": 31,
  "FirstName": "Drew",
  "LastName": "Brees"
}, {
  "Age": 29,
  "FirstName": "Tony",
  "LastName": "Romo"
}]

“D” nin nereden geldiği hakkında hiçbir fikrim yok. Ayrıca kaçış karakterlerinin neden eklendiğine dair hiçbir fikrim yok. Varlığım aşağıdaki gibi görünüyor:

[DataContract]
public class Person
{
    [DataMember]
    public string FirstName { get; set; }

    [DataMember]
    public string LastName { get; set; }

    [DataMember]
    public int Age { get; set; }

    public Person(string firstName, string lastName, int age)
    {
        this.FirstName = firstName;
        this.LastName = lastName;
        this.Age = age;
    }
}

İçeriğin iade edilmesinden sorumlu hizmet şu şekilde tanımlanır:

[ServiceContract(Namespace = "")]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class TestService
{
    [OperationContract]
    [WebGet(ResponseFormat = WebMessageFormat.Json)]
    public string GetResults()
    {
        List<Person> results = new List<Person>();
        results.Add(new Person("Peyton", "Manning", 35));
        results.Add(new Person("Drew", "Brees", 31));
        results.Add(new Person("Tony", "Romo", 29));

        // Serialize the results as JSON
        DataContractJsonSerializer serializer = new DataContractJsonSerializer(results.GetType());
        MemoryStream memoryStream = new MemoryStream();
        serializer.WriteObject(memoryStream, results);

        // Return the results serialized as JSON
        string json = Encoding.Default.GetString(memoryStream.ToArray());
        return json;
    }
}

Bir WCF hizmetinden “temiz” JSON'u nasıl iade edebilirim? Teşekkür ederim!


SOAP XML döndürmelidir. JSON döndürmek için bir REST uç noktası kullanabilirsiniz. Bir göz atın stackoverflow.com/questions/186631/…
Akira Yamamoto

4
Bu arada, başka biri bununla karşılaşırsa ve "d" özelliğinin neden orada olduğunu merak ederse, bir JSON güvenlik açığını düzeltmek için oradadır . Kaldırmak sizi tekrar savunmasız hale getirir.
Alex

4
@Alex - bu Güvenlik Açığı, modern tarayıcılarda artık mümkün olmayan Array nesnesinin yeniden tanımlanmasına bağlıdır. Bkz. Stackoverflow.com/questions/16289894/…
Cheeso

Bu iyi. :) Cevabımın yarısı hala doğru - bu güvenlik açığını düzeltmek için oradaydı.
Alex

Yanıtlar:


213

GetResults'unuzun dönüş türünü değiştirin List<Person>.
Listeyi bir json dizesine serileştirmek için kullandığınız kodu ortadan kaldırın - WCF bunu sizin için otomatik olarak yapar.

Person sınıfı için tanımınızı kullanarak bu kod benim için çalışır:

public List<Person> GetPlayers()
{
    List<Person> players = new List<Person>();
    players.Add(new  Person { FirstName="Peyton", LastName="Manning", Age=35 } );
    players.Add(new  Person { FirstName="Drew", LastName="Brees", Age=31 } );
    players.Add(new  Person { FirstName="Brett", LastName="Favre", Age=58 } );

    return players;
}

Sonuçlar:

[{"Age":35,"FirstName":"Peyton","LastName":"Manning"},  
 {"Age":31,"FirstName":"Drew","LastName":"Brees"},  
 {"Age":58,"FirstName":"Brett","LastName":"Favre"}]

(Hepsi bir satırda)

Ayrıca yöntemde bu özniteliği kullandım:

[WebInvoke(Method = "GET",
           RequestFormat = WebMessageFormat.Json,
           ResponseFormat = WebMessageFormat.Json,
           UriTemplate = "players")]

Method = "GET" ile WebInvoke WebGet ile aynıdır, ancak yöntemlerimin bazıları POST olduğundan tutarlılık için tüm WebInvoke'u kullanıyorum.

UriTemplate, yöntemin kullanılabilir olduğu URL'yi ayarlar. Böylece bir GET yapabilirim http://myserver/myvdir/JsonService.svc/playersve sadece işe yarıyor.

Ayrıca URI'deki .svc'den kurtulmak için IIRF'ye veya başka bir URL yeniden yazara göz atın.


Cheeso - Bu soruyu göndermeden önce bu yaklaşımı denedim. Bu yaklaşımı kullandığımda, "'UriTemplate' kullanan uç noktalar '' System.ServiceModel.Description.WebScriptEnablingBehavior 'ile kullanılamaz" hata mesajı alıyorum. Neyi yanlış yapıyorum? Teşekkür ederim!
user208662

28
.config dosyanızda <webScriptEnablingBehavior /> yerine <webHttp /> kullanın.
Cheeso

9
Tamam, yerini <enableWebScript /> ile <webHttp /> ve bu çalıştı.
MGOwen

3
MGowen - FYI, yeni bir soru sorduğunda en iyi seçenek, soruyu eski bir cevaba yorum olarak göndermek yerine ... yeni bir soru açmaktır.
Cheeso

5
Favre orada ne yaptığını görür.
ruffin

93

Hizmet sınıflarınıza sabit kodlama nitelikleri olmadan güzel json istiyorsanız,

kullanmak <webHttp defaultOutgoingResponseFormat="Json"/>sizin davranış config



8

Aynı sorunla karşı karşıya kaldım ve "WebMessageBodyStyle.Bare" için BodyStyle öznitelik değerini değiştirerek çözdüm:

[OperationContract]
[WebGet(BodyStyle = WebMessageBodyStyle.Bare, RequestFormat = WebMessageFormat.Json,
        ResponseFormat = WebMessageFormat.Json, UriTemplate = "GetProjectWithGeocodings/{projectId}")]
GeoCod_Project GetProjectWithGeocodings(string projectId);

Döndürülen nesne artık sarılmayacak.


1

GET Yöntemi kullandığınızda, sözleşme bu olmalıdır.

[WebGet(UriTemplate = "/", BodyStyle = WebMessageBodyStyle.Bare, ResponseFormat = WebMessageFormat.Json)]
List<User> Get();

bununla biz boot parametresi olmayan bir json var

Aldo Flores @alduar http://alduar.blogspot.com


1

IServece.cs içinde aşağıdaki etiketi ekleyin: BodyStyle = WebMessageBodyStyle.Bare

 [WebInvoke(Method = "GET", ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare, UriTemplate = "Getperson/{id}")]

    List<personClass> Getperson(string id);

BodyStyle'ın sonucu neden etkileyebileceğini de açıklayabilir misiniz?
MBH
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.