2016-08-21 223 views
16

根據JSON spec,表示空值的正確方法是文字null爲什麼WCF/JSON不爲null返回值返回`null`?

如果是這樣,爲什麼WCF返回空響應而不是null?這是一個錯誤還是這種行爲記錄在某處?

完成攝製例如:

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

預期結果:

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

實際結果:

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

$ 
+0

因爲空值可以用許多不同的方式表示。看到這篇文章的更多信息:http://stackoverflow.com/questions/21120999/representing-null-in-json –

+0

@TomRedfern:該帖子的接受答案還聲稱,null應該表示null應該根據JSON規範。我的問題是*爲什麼* WCF偏離規範。 – Heinzi

+0

根據[最近的答案](http://stackoverflow.com/a/39933043/11683),我想知道你的服務是否實際上用'Content-Type:application/json'響應? – GSerg

回答

6

link以JSON規範包括這些有趣的臺詞:

JSON是建立在兩個結構:

  1. 名稱/值對的集合。在各種語言中,這被實現爲對象,記錄,結構,字典,散列表,鍵列表或關聯數組。

  2. 有序的值列表。在大多數語言中,這是作爲數組,矢量,列表或序列實現的。

所以,在我的理解,你的返回類型不符合規範。

  • 無論是public string GetNull() { return null; }

  • 也不public string GetSomeString() { return "SomeString"; }

要fullfill你將不得不改變他們要匹配1號或2的規格。

  1. 使用結構。 public struct structWithNull{public object resp;}默認值是零,那麼返回public structWithNull GetNull() {return new structWithNull() ; }null value returned by struct

  2. 大小爲一的陣列使用。 public object[] GetNullArray() {return new object[1] ; }。默認值再次爲空;返回: null value returned by one element array

這在我看來,JSON是基於封裝數據,如XML,這裏總是需要一個父節點。所以我猜想沒有其他解決方案來使用struct/class(#1)或數組(#2)。

更新:

我發現了一個線索這裏:rfc7159

注意,JSON的某些以前的規格限制的JSON文本是一個對象或數組。只生成對象或數組的JSON文本被調用的實現將是可互操作的,因爲所有實現都將接受這些JSON文本爲符合條件的JSON文本。

如果我理解正確這,你是正確的,空今天應該返回,因爲它是一種原始的,但不會因爲主要的重點可能的唯一對象和基於陣列版本的舊規定的行爲。

最後我相信只有微軟能完全回答這個問題。

+0

這是一個有趣的觀點,但我相信你從JSON主頁的引用不*暗示有效的JSON文本必須有一個對象或數組作爲基本元素。如果我們查看從頁面鏈接的ECMA-404 PDF,我們看到*任何* JSON值都是有效的JSON文本。引用(強調我的):* JSON文本是由Unicode代碼點形成的符號序列,符合JSON **值** 語法。 [...] JSON值可以是一個對象,數組,數字,字符串,'true','false'或**'null **。*因此,'null',''''和'「 abc「'是有效的JSON文本,但」(空)不會。 – Heinzi

+0

我發佈了一個更新到我的答案。 –

0

在我看來WCF或其他方式都是數據傳輸契約,而所有的數據庫都是以字符串的形式存在的。區別只是如何縮小字符串表單。
此方法只是返回一個字符串,不管客戶端如何獲取數據格式如何,所以它不需要是json格式。
如果只是返回字符串"null"代表null如果我想返回字符串"null"而不是null。它會感到困惑。當然你可以使用ESC字符來解決它。也許他們認爲沒有更好的。
如果客戶端使用json格式數據,你只需返回一個字符串"null",然後客戶端反序列化它得到一個null,一切都很好。無論如何,返回是無關緊要的,但如何簽約數據格式。

+0

是的,唯一重要的是發送者和接收者知道消息的含義。 –

-1

如果你想實際空值在JSON格式的WCF響應中返回,你應該定義一個datacontract並沒有初始化它

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

現在,在您操作約定返還像這樣

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

然後你會在你的JSON響應中爲null值。

希望它有幫助