33

I want to convert a .Net object in to JSON in the view. My view model is like this,

public class ViewModel{
    public SearchResult SearchResult { get; set;}    
}    

public class SearchResult {
    public int Id { get; set; }
    public string Text{ get; set; }
}

I want to convert Model.SearchResult in to a JSON object. Currenty I'm doing it like this:

System.Web.Script.Serialization.JavaScriptSerializer serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
//....
var s = @serializer.Serialize(Model.Institution);

but the result is like this,

var s = { "Name":"a","Id":1};
Create:228Uncaught SyntaxError: Unexpected token &

How can I convert this correctly in to a JSON object?

Rory McCrossan
  • 331,213
  • 40
  • 305
  • 339
Jayantha Lal Sirisena
  • 21,216
  • 11
  • 71
  • 92

3 Answers3

65

Try using this method:

@Html.Raw(Json.Encode(Model.Content))

Kyeotic
  • 19,697
  • 10
  • 71
  • 128
35

I use this helper since asp.net mvc 2

public static MvcHtmlString ToJson(this HtmlHelper html, object obj)
{
  JavaScriptSerializer serializer = new JavaScriptSerializer();
  return MvcHtmlString.Create(serializer.Serialize(obj));
}

public static MvcHtmlString ToJson(this HtmlHelper html, object obj, int recursionDepth)
{
  JavaScriptSerializer serializer = new JavaScriptSerializer();
  serializer.RecursionLimit = recursionDepth;
  return MvcHtmlString.Create(serializer.Serialize(obj));
}

And in the view:

  <script>
    var s = @(Html.ToJson(Model.Content));
  </script>

I should replace serializer with the JSON.Encode(..) now, like mentionned in the refer by Hemant. (It use itself JavaScriptSerializer).

The source of your problem is the "@" which HTML encode the JSON. You can use @Html.Raw(..) to avoid this behavior.

+: take a look for Json.Net http://json.codeplex.com/

JSON.Net update

I've updated the helper a while ago with JSON.net (much better).

It seems some users continue to read, upvote and use the old code. I'd like they use a better way, with the new version below, or by using NGon like Matthew Nichols has noticed it in a comment.

Here's the code:

using System;
using Newtonsoft.Json;

namespace System.Web.Mvc
{
  public static class HtmlHelperExtensions
  {
    private static readonly JsonSerializerSettings settings;

    static HtmlHelperExtensions()
    {
      settings = new JsonSerializerSettings();
      // CamelCase: "MyProperty" will become "myProperty"
      settings.ContractResolver = new Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver();
    }

    public static MvcHtmlString ToJson(this HtmlHelper html, object value)
    {
      return MvcHtmlString.Create(JsonConvert.SerializeObject(value, Formatting.None, settings));
    }
  }
}
Community
  • 1
  • 1
Loic El Thesea
  • 704
  • 7
  • 17
  • 1
    I typically set up NGon (https://github.com/brooklynDev/NGon) for this sort of thing but if I am just using in one spot this is a nice solution. – Matthew Nichols Mar 15 '13 at 17:20
1

This is an update to my original answer and I'll admit that as a result of the insistent badgering of @Tyrsius :D who refused to give up the fact that I could not access vars created in <script> tags in my MVC 5 cshtml page from my .js libraries in separate files, I discovered that if I placed the script tags inside of the @section scripts statement block that the vars created there did make the global scope and was available to my plugin widgets. I have not used it within any of my more complex apps as of yet, but did use it in a protoType of another app and the answer is below. Now @Html.Raw(...) works and I was able to serialize an object that I could immediately use.

This is something I will be using from now on... thanks again for hanging in there with me @Tyrsius

   @section scripts
    {
    <script type="text/javascript">
        @using MRTCProtoType.Models.ControllerData.Contracts

        var testVar = @Html.Raw(JsonConvert.SerializeObject(WMMWorkloadTestData.getWorkloadTestData()));
    </script>
        @Scripts.Render("~/bundles/homeworkflow")
    }

The following code is in a separate .js file

$(document).ready(function() {  
    alert(JSON.stringify(testVar));
});
Clarence
  • 101
  • 1
  • 9
  • This is an interesting "gotcha" that I haven't run into before, thank you for including it =) – Kyeotic Sep 30 '16 at 20:49
  • 1
    Thanks for nudge... it made me do the work to find a much better solution... notice the slight of hand cred I gave u lol... – Clarence Sep 30 '16 at 20:50