3

I have an action that returns a JsonResult in my ASP.Net MVC4 application. I'm setting the Data property to an array of pre-defined classes. My issue is that I want to serialize with different property names. No matter what attributes I use, the object is serialized with the pre-defined property names. I've tried the following with no results:

[DataMember(Name = "iTotalRecords")]
[JsonProperty(PropertyName = "iTotalRecords")]
public int TotalRecords { get; set; }

I know "iTotalRecords" seems silly, but this action is for supporting a jQuery plugin that expects "iTotalRecords" and not "TotalRecords". Of course, I want to use names that make sense in my code-behind.

What serializer is used to parse JsonResult? Is there anything I can do or do I have to re-think returning JsonResult as an action result?

Jason Butera
  • 2,376
  • 3
  • 29
  • 46
  • 1
    Have you seen [this thread](http://stackoverflow.com/questions/1302946/asp-net-mvc-controlling-serialization-of-property-names-with-jsonresult)? – chrisfrancis27 Sep 19 '12 at 14:47

3 Answers3

4

What serializer is used to parse JsonResult?

JavaScriptSerializer.

Is there anything I can do or do I have to re-think returning JsonResult as an action result?

Two possibilities come to mind:

  • define a view model and then map your domain model to the view model
  • write a custom action result that uses Json.NET or DataContractJsonSerializer and which allow you to control the names of the serialized properties. The following question illustrates this.
Community
  • 1
  • 1
Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
4

Thanks for the suggestions. I went ahead and created an ActionResult that uses Json.Net:

public class JsonNetActionResult : ActionResult
{
    public Object Data { get; private set; }

    public JsonNetActionResult(Object data)
    {
        this.Data = data;
    }

    public override void ExecuteResult(ControllerContext context)
    {
        context.HttpContext.Response.ContentType = "application/json";
        context.HttpContext.Response.Write(JsonConvert.SerializeObject(Data));
    }
}

FYI, it looks like Json.Net respects both [DataMember] and [JsonProperty], but [JsonProperty] will trump [DataMember] if they differ.

Jason Butera
  • 2,376
  • 3
  • 29
  • 46
  • I like this! You should add an example usage `public virtual ActionResult GetByCatalogId(Guid catalogId) { var o = new MyObject(); return new JsonNetActionResult(o); }` – styfle Jul 28 '16 at 16:18
1

I've found part of the solution here and on SO

public class JsonNetResult : ActionResult
    {
        public Encoding ContentEncoding { get; set; }
        public string ContentType { get; set; }
        public object Data { get; set; }

        public JsonSerializerSettings SerializerSettings { get; set; }
        public Formatting Formatting { get; set; }

        public JsonNetResult(object data, Formatting formatting)
            : this(data)
        {
            Formatting = formatting;
        }

        public JsonNetResult(object data):this()
        {
            Data = data;
        }

        public JsonNetResult()
        {
            Formatting = Formatting.None;
            SerializerSettings = new JsonSerializerSettings();
        }

        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;

            var writer = new JsonTextWriter(response.Output) { Formatting = Formatting };
            var serializer = JsonSerializer.Create(SerializerSettings);
            serializer.Serialize(writer, Data);
            writer.Flush();
        }
    }

So that in my controller, I can do that

        return new JsonNetResult(result);

In my model, I can now have:

    [JsonProperty(PropertyName = "n")]
    public string Name { get; set; }

Note that now, you have to set the JsonPropertyAttribute to every property you want to serialize.

Daniel
  • 9,312
  • 3
  • 48
  • 48