Làm cách nào để trả lại JSON sạch từ Dịch vụ WCF?


233

Tôi đang cố gắng trả lại một số JSON từ dịch vụ WCF. Dịch vụ này chỉ đơn giản trả về một số nội dung từ cơ sở dữ liệu của tôi. Tôi có thể lấy dữ liệu. Tuy nhiên, tôi lo ngại về định dạng JSON của tôi. Hiện tại, JSON được trả về được định dạng như thế này:

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

Trong thực tế, tôi muốn JSON của tôi được định dạng càng sạch càng tốt. Tôi tin rằng (tôi có thể không chính xác), rằng cùng một bộ sưu tập kết quả, được trình bày trong JSON sạch, sẽ trông giống như vậy:

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

Tôi không có ý tưởng về nơi mà diếp cá đến từ đâu. Tôi cũng không biết tại sao các ký tự thoát được chèn vào. Thực thể của tôi trông như sau:

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

Dịch vụ chịu trách nhiệm trả lại nội dung được xác định là:

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

Làm cách nào để tôi trả lại sạch JSON JSON từ dịch vụ WCF? Cảm ơn bạn!


SOAP sẽ trả về XML. Bạn có thể sử dụng điểm cuối REST để trả về JSON. Hãy xem stackoverflow.com/questions/186631/ Mạnh
Akira Yamamoto

4
Nhân tiện, nếu có ai khác bắt gặp điều này và tự hỏi tại sao thuộc tính "d" lại ở đó, thì nó sẽ ở đó để vá lỗ hổng JSON . Loại bỏ nó làm cho bạn dễ bị tổn thương một lần nữa.
Alex

4
@Alex - Tính dễ bị tổn thương đó phụ thuộc vào việc xác định lại đối tượng Array, điều này không còn có thể có trong các trình duyệt hiện đại. Xem stackoverflow.com/questions/16289894/...
Cheeso

Điều đó thật tốt. :) Một nửa câu trả lời của tôi vẫn đúng - nó đã ở đó để vá lỗ hổng đó.
Alex

Câu trả lời:


213

Thay đổi kiểu trả về của GetResults của bạn thành List<Person>.
Loại bỏ mã mà bạn sử dụng để tuần tự hóa Danh sách thành chuỗi json - WCF tự động thực hiện việc này cho bạn.

Sử dụng định nghĩa của bạn cho lớp Person, mã này hoạt động với tôi:

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

các kết quả:

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

(Tất cả trên một dòng)

Tôi cũng đã sử dụng thuộc tính này trên phương thức:

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

WebInvoke với Phương thức = "GET" giống như WebGet, nhưng vì một số phương thức của tôi là POST, tôi sử dụng tất cả WebInvoke để thống nhất.

UriTemplate đặt URL tại đó phương thức khả dụng. Vì vậy, tôi có thể thực hiện một GET http://myserver/myvdir/JsonService.svc/playersvà nó chỉ hoạt động.

Ngoài ra, hãy kiểm tra IIRF hoặc một trình ghi lại URL khác để loại bỏ .svc trong URI.


Cheeso - Tôi đã thử phương pháp này trước khi tôi đăng câu hỏi này. Khi tôi sử dụng phương pháp này, tôi gặp lỗi thông báo "Điểm cuối sử dụng 'UriTemplate' không thể được sử dụng với 'System.ServiceModel.Descrip.WebScriptEneacBehavior'." Tôi đang làm gì sai? Cảm ơn bạn!
dùng208662

28
sử dụng <webHttp /> thay vì <webScriptEneacBehavior /> trong tệp .config của bạn.
Cheeso

9
OK, tôi đã thay thế <enableWebScript /> bằng <webHttp /> và nó đã hoạt động.
MGOwen

3
MGowen - FYI, đặt cược tốt nhất khi đặt câu hỏi mới là ... mở một câu hỏi mới, thay vì đăng câu hỏi dưới dạng nhận xét cho câu trả lời cũ.
Cheeso

5
Favre thấy những gì bạn đã làm ở đó.
ruffin

93

Nếu bạn muốn json đẹp mà không cần thuộc tính mã hóa vào các lớp dịch vụ của bạn,

sử dụng <webHttp defaultOutgoingResponseFormat="Json"/>trong cấu hình hành vi của bạn



8

Tôi đã đối mặt với cùng một vấn đề và giải quyết nó bằng cách thay đổi giá trị thuộc tính BodyStyle thành "WebMessageBodyStyle.Bare":

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

Các đối tượng trả lại sẽ không còn được bọc.


1

Khi bạn đang sử dụng Phương thức GET, hợp đồng phải là thế này.

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

với điều này, chúng ta có một json không có tham số khởi động

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


1

Trong IServece.cs của bạn thêm thẻ sau: BodyStyle = WebMessageBodyStyle.Bare

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

    List<personClass> Getperson(string id);

bạn cũng có thể giải thích tại sao BodyStyle có thể ảnh hưởng đến kết quả?
MBH
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.