Reputation: 172270
According to the JSON spec, the correct way to represent a null value is the literal null
.
If that is the case, why does WCF return an empty response instead of null
? Is this a bug or is this behaviour documented somewhere?
Complete repro example:
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();
}
}
Expected result:
$ curl http://localhost:8000/GetSomeString && echo
"SomeString"
$ curl http://localhost:8000/GetNull && echo
null
$
Actual result:
$ curl http://localhost:8000/GetSomeString && echo
"SomeString"
$ curl http://localhost:8000/GetNull && echo
$
Upvotes: 16
Views: 1305
Reputation: 1791
If you want actual null values to be returned in your wcf response in json format you should define a datacontract and return it without initializing it
[DataContract]
public class Employee
{
[DataMember]
public string id { get; set; }
}
Now in your operation contract return it like this
[OperationContract(), WebGet(ResponseFormat = WebMessageFormat.Json)]
public string GetNull() { return new Employee(); }
Then you will null values in your json response.
Hope it helps
Upvotes: -1
Reputation: 622
Your link to json specification includes these interesting lines:
JSON is built on two structures:
A collection of name/value pairs. In various languages, this is realized as an object, record, struct, dictionary, hash table, keyed list, or associative array.
An ordered list of values. In most languages, this is realized as an array, vector, list, or sequence.
So, in my understanding, your return types aren't conforming to the specification.
Neither public string GetNull() { return null; }
nor public string GetSomeString() { return "SomeString"; }
To fullfill the specifications you would have to change them to match either #1 or #2.
A struct is used. public struct structWithNull{public object resp;}
The default value is null, so public structWithNull GetNull() {return new structWithNull() ; }
returns:
An array of size one is used. public object[] GetNullArray() {return new object[1] ; }
. The default value is again null; it returns:
It seems to me that JSON is based of encapsulating data, like XML, where a parent node is always needed. So I guess that there is no other solution to this as to use a struct/class(#1) or an array(#2).
Update:
I found a clue here: rfc7159
Note that certain previous specifications of JSON constrained a JSON text to be an object or an array. Implementations that generate only objects or arrays where a JSON text is called for will be interoperable in the sense that all implementations will accept these as conforming JSON texts.
If I understand this correctly, your are right and null should be returned today as it is a primitive, but won't because the main focus might be on the old specified behavior of the only object and array based versions.
Finally I believe only Microsoft can answer this question completely.
Upvotes: 6
Reputation: 481
In my opinion WCF or other ways are data transfer contract, and all data base on string. Difference just how you contract the string form.
This method just return a string, no matter how's the format only the client can get the data, so it doesn't need to be json format.
If just return string "null"
represent null
what if i want to return string "null"
instead of null
. It'll be confused. Of course you can use ESC characters solve it. Maybe they think nothing is better.
If client use json format data, you just return a string "null"
, then client deserialize it get a null
, everything is ok. Anyway it's doesn't matter what return, but how to contract data format.
Upvotes: 0