Jan Zich
Jan Zich

Reputation: 15333

Escaping JavaScript string literals in views

Is there a utility function for escaping JavaScript in ASP.NET MVC views? I often need to init a little snippet of JavaScript using some values from the view; for instance I may have something like:

<script type="text/javascript">
var page = new Page({ currentUser: "<%= Model.UserName %>" });
page.init();
</script>

I would expect something like:

<script type="text/javascript">
var page = new Page({ currentUser: "<%= Html.JavaScriptEscape(Model.UserName) %>" });
page.init();
</script>

I could, of course, write the function myself. But since there are already built-in utilities form HTML encoding, and since one of the selling points of ASP.NET MVC is that the <% %> is the default rendering mode, and since what I'm trying to achieve is quite common, it makes me wonder why I cannot find anything like that already built-in. Is there, for instance, an easy and elegant way to serialize an object to JSON in views?

Or am doing something against ASP.NET MVC principles? When I hit a problem like this, it usually makes it think that either I’m doing something wrong since I assume that the framework designers spent some time thinking about real world scenarios.

Upvotes: 31

Views: 17011

Answers (4)

Rick Love
Rick Love

Reputation: 12790

In my case I needed a string not a json object and this is for Asp.Net Core:

@functions{
    public Microsoft.AspNetCore.Html.IHtmlContent ToJS(string value)
    {
        return Html.Raw("'" + value.Replace("'", "\\'").Replace("\r", "\\r").Replace("\n", "\\n") + "'");
    }

    public Microsoft.AspNetCore.Html.IHtmlContent ToJS(int value)
    {
        return Html.Raw("" + value);
    }
}

This will escape the ' and end of line characters. Also it leaves numbers (int) as a number. This could be overloaded to include float, decimal, etc. as needed.

So, I don't have to think about it or do anything different for each type:

var serverName = @ToJS(m.ServerName);
var appSiteUrl = @ToJS(m.SiteUrl);
var facebookId = @ToJS(m.FacebookAppId);

Upvotes: 0

sshine
sshine

Reputation: 16135

In MVC 5 using Razor templates, the following is possible:

<script type="text/javascript">
    var page = new Page({ currentUser: @Html.Raw(Json.Encode(Model.UserName)) });
    page.init();
</script>

Upvotes: 10

StriplingWarrior
StriplingWarrior

Reputation: 156634

In .NET 4, The HttpUtility class has a variety of static encoding methods for various contexts, including a JavaScriptStringEncode method for this particular purpose.

It's often simpler to just use JSON deserialization, though.

Upvotes: 51

Jan Zich
Jan Zich

Reputation: 15333

After some time working in ASP.NET MVC, I concluded that (most likely) there is no build-in helper for it. Of course, it's trivial to write your own. Here is it for the sake of completeness:

using System.Web.Mvc;
using System.Web.Script.Serialization;

namespace MyProject.Helpers
{
    public static class JsonExtensions
    {
        public static string Json(this HtmlHelper html, object obj)
        {
            JavaScriptSerializer jsonSerializer = new JavaScriptSerializer();
            return jsonSerializer.Serialize(obj);
        }
    }
}

In a view, it can be used as follows:

<script type="text/javascript">
var page = new Page(<%= Html.Json(new { currentUser: Model.UserName } ) %>);
page.init();
</script>

Upvotes: 8

Related Questions