Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't WCF/JSON return `null` for a null return value?

Tags:

json

c#

wcf

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

$
like image 649
Heinzi Avatar asked Aug 21 '16 15:08

Heinzi


People also ask

Does JSON allow null values?

JSON has a special value called null which can be set on any type of data including arrays, objects, number and boolean types.

How do you indicate a null value in JSON?

If you want to represent a null value in JSON, the entire JSON string (excluding the quotes containing the JSON string) is simply null . No braces, no brackets, no quotes.

Can we return JSON from WCF service?

You can use a REST endpoint to return JSON.

How check JSON value is null or not in C#?

SerializeObject(new RootObject { catalog_only =new CatalogOnly(), collection = new Collection(), configurator =null, slug="Test", title="Test" }); var t = JsonConvert. DeserializeObject<RootObject>(k). configurator; Here configurator is null.


1 Answers

Your link to json specification includes these interesting lines:

JSON is built on two structures:

  1. 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.

  2. 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.

  1. A struct is used. public struct structWithNull{public object resp;} The default value is null, so public structWithNull GetNull() {return new structWithNull() ; } returns: null value returned by struct

  2. An array of size one is used. public object[] GetNullArray() {return new object[1] ; }. The default value is again null; it returns: null value returned by one element array

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.

like image 172
Florian p.i. Avatar answered Oct 25 '22 12:10

Florian p.i.