9

I have a action which returns an JsonResult for an object of a particular class. I have decorated the properties of this class with some attrib to avoid null fields. Class definition is:

    private class GanttEvent
    {
        public String name { get; set; }

        [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
        public String desc { get; set; }

        [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
        public List<GanttValue> values { get; set; }
    }

And in my Action i use an object

    var res = new List<GanttEvent>();

which I return using:

    return Json(res, JsonRequestBehavior.AllowGet);

Unfortunatelly, I'm still receiving null values at output:

    [{"name":"1.1 PREVIOS AL INICIO ","desc":null,"values":null},{"name":"F04-PGA-S10","desc":"Acta preconstrucción","values":null},{"name":"F37-PGA-S10","desc":"Plan de inversión del anticipo","values":null},{"name":"F09-PGA-S10","desc":"Acta de vecindad","values":null},{"name":"F05-PGA-S10","desc":"Acta de inicio","values":null},{"name":"F01-PGA-S10","desc":"Desembolso de anticipo","values":null}]

Am I missing something or doing something wrong?

tereško
  • 58,060
  • 25
  • 98
  • 150
Farlop
  • 690
  • 1
  • 6
  • 20

3 Answers3

8

As stated by Brad Christie, MVC4 stills uses JavaScriptSerializer, so in order to get your object serialized by Json.Net, you will have to perform several steps.

First, inherit a new class JsonNetResult from JsonResult as follows (based on this solution):

public class JsonNetResult : JsonResult
{
    public JsonNetResult()
    {
        this.ContentType = "application/json";
    }

    public JsonNetResult(object data, string contentType, Encoding contentEncoding, JsonRequestBehavior jsonRequestBehavior)
    {
        this.ContentEncoding = contentEncoding;
        this.ContentType = !string.IsNullOrWhiteSpace(contentType) ? contentType : "application/json";
        this.Data = data;
        this.JsonRequestBehavior = jsonRequestBehavior;
    }

    public override void ExecuteResult(ControllerContext context)
    {
        if (context == null)
            throw new ArgumentNullException("context");

        var response = context.HttpContext.Response;

        response.ContentType = !String.IsNullOrEmpty(ContentType) ? ContentType : "application/json";

        if (ContentEncoding != null)
            response.ContentEncoding = ContentEncoding;

        if (Data == null)
            return;

        // If you need special handling, you can call another form of SerializeObject below
        var serializedObject = JsonConvert.SerializeObject(Data, Formatting.None);
        response.Write(serializedObject);
    }
}

Then, in your controller, override the Json method to use the new class:

protected override JsonResult Json(object data, string contentType, Encoding contentEncoding, JsonRequestBehavior behavior)
{
    return new JsonNetResult(data, contentType, contentEncoding, behavior);
}
Community
  • 1
  • 1
Farlop
  • 690
  • 1
  • 6
  • 20
  • 1
    Don't know if this answer is still relevant, but I needed something like this, and did a c/p of your code. Unfortunately, it didn't work as expected, but I edited your JsonNetResult class slightly: var serializedObject = JsonConvert.SerializeObject(Data, Formatting.None, new JsonSerializerSettings{ NullValueHandling = NullValueHandling.Ignore}); ...and now it works perfectly. thanks! – robertpaulsen May 26 '16 at 14:06
1

Controller.Json uses the JavaScriptSerializer not the Newtonsoft Json library (which is where the JsonPropertyAttribute originates from).

You'll either need to use the Newtonsoft library library and return the serialized result that way, or you continue calling Json and write a converter that will ignore nulls.

Brad Christie
  • 100,477
  • 16
  • 156
  • 200
  • Thanks, I was suspicious about that, and you confirmed my thoughs. In the end, Json.Net is the default serializer, but just for **WebAPI**, not for regular MVC site. – Farlop Nov 09 '12 at 09:28
0

My suggestion would be to see what happens if you just serialize one GanttEvent object to JSON. Also check your call to Json is appropriate.

Bradley Thomas
  • 4,060
  • 6
  • 33
  • 55