2016-08-21 23 views
16

Theo số JSON spec, cách chính xác để biểu thị giá trị rỗng là chữ số null.Tại sao WCF/JSON không trả về `null` cho giá trị trả về null?

Nếu đúng như vậy, tại sao WCF trả về phản hồi trống thay vì null? Đây có phải là lỗi hoặc hành vi này được ghi lại ở đâu đó không?

Hoàn dụ repro:

using System; 
using System.ServiceModel; 
using System.ServiceModel.Web; 

[ServiceContract()] 
public class Service1 
{ 
    [OperationContract(), WebGet(ResponseFormat = WebMessageFormat.Json)] 
    public string GetSomeString() { return "SomeString"; } 

    [OperationContract(), WebGet(ResponseFormat = WebMessageFormat.Json)] 
    public string GetNull() { return null; } 
} 

public class Host 
{ 
    public static void Main() 
    { 
     // Very simple WCF server 
     var host = new WebServiceHost(typeof(Service1), new Uri("http://localhost:8000/")); 
     host.AddServiceEndpoint(typeof(Service1), new WebHttpBinding() { 
      HostNameComparisonMode = HostNameComparisonMode.Exact 
     }, ""); 

     host.Open(); 
     Console.WriteLine("Service is running, press enter to quit..."); 
     Console.ReadLine(); 
     host.Close(); 
    } 
} 

Kết quả mong đợi:

$ curl http://localhost:8000/GetSomeString && echo 
"SomeString" 
$ curl http://localhost:8000/GetNull && echo 
null 
$ 

kết quả thực tế:

$ curl http://localhost:8000/GetSomeString && echo 
"SomeString" 
$ curl http://localhost:8000/GetNull && echo 

$ 
+0

Bởi vì giá trị null có thể được biểu diễn theo nhiều cách khác nhau. Xem bài đăng này để biết thêm: http://stackoverflow.com/questions/21120999/representing-null-in-json –

+0

@TomRedfern: Câu trả lời được chấp nhận của bài đăng đó cũng tuyên bố rằng 'null' là cách null sẽ được biểu diễn theo thông số JSON. Câu hỏi của tôi là * tại sao * WCF lệch khỏi spec. – Heinzi

+0

Trong ánh sáng của [câu trả lời gần đây] (http://stackoverflow.com/a/39933043/11683), tôi tự hỏi nếu dịch vụ của bạn thực sự phản hồi với 'Content-Type: application/json'? – GSerg

Trả lời

6

bạn link đặc điểm kỹ thuật json bao gồm những dòng này thú vị:

JSON được xây dựng trên hai cấu trúc:

  1. Một bộ sưu tập các cặp tên/giá trị. Trong các ngôn ngữ khác nhau, điều này được thực hiện như một đối tượng, bản ghi, cấu trúc, từ điển, bảng băm, khóa danh sách hoặc mảng kết hợp.

  2. Danh sách có thứ tự các giá trị. Trong hầu hết các ngôn ngữ, điều này được thực hiện dưới dạng mảng, vectơ, danh sách hoặc chuỗi.

Vì vậy, theo hiểu biết của tôi, loại trả về của bạn không tuân thủ đặc điểm kỹ thuật.

  • Cả public string GetNull() { return null; }

  • cũng không public string GetSomeString() { return "SomeString"; }

Để fullfill các thông số kỹ thuật bạn sẽ phải thay đổi chúng để phù hợp với một trong hai # 1 hoặC# 2.

  1. Cấu trúc được sử dụng. public struct structWithNull{public object resp;} Giá trị mặc định bằng không, vì vậy public structWithNull GetNull() {return new structWithNull() ; } trả về: null value returned by struct

  2. Một mảng kích thước được sử dụng. public object[] GetNullArray() {return new object[1] ; }. Giá trị mặc định là một lần nữa null; nó sẽ trả về: null value returned by one element array

Dường như với tôi rằng JSON được dựa trên đóng gói dữ liệu, như XML, nơi một nút cha là luôn luôn cần thiết. Vì vậy, tôi đoán rằng không có giải pháp khác cho điều này là sử dụng một struct/class (# 1) hoặc một mảng (# 2).

Cập nhật:

Tôi tìm thấy một đầu mối ở đây: rfc7159

Lưu ý rằng một số thông số kỹ thuật trước của JSON hạn chế một văn bản JSON là một đối tượng hoặc một mảng. Việc triển khai chỉ tạo ra các đối tượng hoặc mảng nơi một văn bản JSON được gọi cho sẽ tương thích với nhau theo nghĩa là tất cả các triển khai sẽ chấp nhận chúng như là các văn bản JSON phù hợp.

Nếu tôi hiểu điều này một cách chính xác, bạn đúng và không được trả về ngày hôm nay vì nó là nguyên thủy, nhưng sẽ không tập trung chính vào hành vi được chỉ định cũ của phiên bản dựa trên mảng và đối tượng .

Cuối cùng tôi tin rằng chỉ có Microsoft mới có thể trả lời câu hỏi này hoàn toàn.

+0

Đây là một điểm thú vị, nhưng tôi tin rằng trích dẫn của bạn từ trang chủ JSON không * không * ngụ ý rằng một văn bản JSON hợp lệ phải có một đối tượng hoặc mảng làm phần tử cơ bản. Nếu chúng ta nhìn vào tệp PDF ECMA-404 được liên kết từ trang, chúng ta thấy rằng * bất kỳ * giá trị JSON nào là một văn bản JSON hợp lệ. Để trích dẫn (nhấn mạnh mỏ): * Văn bản JSON là một chuỗi mã thông báo được tạo thành từ các điểm mã Unicode tuân theo giá trị JSON ** ** ngữ pháp. [...] Giá trị JSON có thể là đối tượng, mảng, số, chuỗi, 'true',' false' hoặc ** 'null' **. * Như vậy,' null', '" "' và '" abc "' sẽ là các văn bản JSON hợp lệ, nhưng '' (trống) sẽ không. – Heinzi

+0

Tôi đã đăng một bản cập nhật nhỏ cho câu trả lời của mình. –

0

Theo ý kiến ​​của tôi WCF hoặc các cách khác là hợp đồng chuyển dữ liệu và tất cả cơ sở dữ liệu trên chuỗi. Sự khác biệt chỉ là cách bạn ký hợp đồng biểu mẫu chuỗi.
Phương thức này chỉ trả về một chuỗi, cho dù định dạng của máy khách chỉ có thể lấy dữ liệu, vì vậy nó không cần định dạng json.
Nếu chỉ trả lại chuỗi "null" đại diện cho null nếu tôi muốn trả về chuỗi "null" thay vì null. Nó sẽ bị nhầm lẫn. Tất nhiên bạn có thể sử dụng ký tự ESC giải quyết nó. Có lẽ họ nghĩ không có gì tốt hơn.
Nếu khách hàng sử dụng dữ liệu định dạng json, bạn chỉ cần trả về một chuỗi "null", sau đó khách hàng deserialize nó có được một null, mọi thứ đều ổn. Dù sao nó không quan trọng những gì trở lại, nhưng làm thế nào để hợp đồng định dạng dữ liệu.

+0

Có, điều quan trọng duy nhất của nó là người gửi và người nhận biết thông điệp có ý nghĩa gì. –

-1

Nếu bạn muốn các giá trị null thực tế để được trả lại trong phản ứng WCF bạn ở định dạng json bạn nên xác định một DataContract và gửi lại mà không cần khởi tạo nó

[DataContract] 
public class Employee 
{ 
[DataMember] 
public string id { get; set; } 
} 

Bây giờ trong hợp đồng hoạt động của bạn trở lại nó như thế này

[OperationContract(), WebGet(ResponseFormat = WebMessageFormat.Json)] 
public string GetNull() { return new Employee(); } 

Sau đó, bạn sẽ vô giá trị trong phản hồi json của mình.

Hy vọng điều này sẽ giúp

Các vấn đề liên quan