2

So, I have a some json data which I create in my controller like so:

Notes = JsonConvert.SerializeObject(contact.Notes.OrderBy(x => x.DateLogged).Select(x => new 
            {
                id = x.Id,
                date = x.DateLogged,
                content = x.Content,
                logged = x.Username
            }))

This then gets passed to the view, now which statment can I do to achieve the results of having a variable contain that json data:

var data = '@Html.Raw(Model.Notes)'

or

var data = JSON.parse('@Html.Raw(Model.Notes)');

EDIT

the content variable holds some "\n" which when passed to the view using the first choice from above generates an error, saying

Unexpected Token

it only does it with \n so what is going wrong here? the bottom method doesn't quite work.

6
  • 2
    Read the generated source. Commented Dec 18, 2013 at 20:28
  • Try one and see if it works...? Commented Dec 18, 2013 at 20:29
  • I always do @Html.Raw(JsonConvert.SerializeObject(Model.Notes)) in the View and send an object from the controller Commented Dec 18, 2013 at 20:33
  • it seems the javascript JSON library doesn't like \n, if i got with the top method with no parse then it works fine Commented Dec 18, 2013 at 20:34
  • No, the generated source probably ends up looking like var data = '...<newline>... and the Javascript parser itself is the one complaining about that newline. You need to escape it somehow. I assume @Html.Raw is meant to be put inside of HTML, not inside of a <script> tag. Commented Dec 18, 2013 at 20:35

2 Answers 2

2
var data = JSON.parse('@Html.Raw(Model.Notes)');

This doesn't work - you can't put a JSON literal inside a JavaScript string. Any backslash in it will be an escape character to the JavaScript parser, not the JSON parser. A newline comes out like:

var data = JSON.parse('{"content": "abc\ndef"}');

which means the string you are asking JSON to parse is:

{"content": "abc

def"}

which is not valid as you can't have a literal newline in a JSON string.

To do this with JSON.parse you would have to JS-string-literal encode the JSON output, so you would end up with "abc\\ndef". The alternative would be to include the JSON directly in the script block as var data = @Html.Raw(Model.Notes);, but there are problems with this to do with the differences between JS and JSON (primarily characters U+2028 and U+2029) and the enclosing HTML context (ie what the sequence </script does).

Getting the escaping right here is harder than it looks, so you should avoid injecting anything into a <script> block. Better to put in-page JSON data in a data- attribute and read it from the DOM; this way you can use the normal HTML escaping Razor gives you by default.

<div id="notes" data-notes="@Model.Notes">

...

var data = JSON.parse(document.getElementById('notes').getAttribute('data-notes'));
Sign up to request clarification or add additional context in comments.

Comments

0

bobince is obviously correct in what he says, it makes so much sense, thanks for that.

However, my solution was to simply do:

var data = @Html.Raw(Model.Notes);

Because, Newtonsoft already has converted it to a proper JSON format, so all it needs to do, is be assigned to a variable to be manipulated.

I think grabbing the content from a the HTML DOM is a bit too much for this.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.