Исключение строковых литералов JavaScript в представлениях
Есть ли функция утилиты для экранирования JavaScript в представлениях ASP.NET MVC? Мне часто нужно запустить небольшой фрагмент JavaScript, используя некоторые значения из представления; например, у меня может быть что-то вроде:
<script type="text/javascript">
var page = new Page({ currentUser: "<%= Model.UserName %>" });
page.init();
</script>
Я бы ожидал чего-то вроде:
<script type="text/javascript">
var page = new Page({ currentUser: "<%= Html.JavaScriptEscape(Model.UserName) %>" });
page.init();
</script>
Я мог бы, конечно, написать эту функцию сам. Но поскольку уже встроенные утилиты формируют HTML-кодирование, и поскольку одна из точек продажи ASP.NET MVC заключается в том, что <%% > является режимом рендеринга по умолчанию, и поскольку то, что я пытаюсь достичь, вполне Общим, это заставляет меня задаться вопросом, почему я не могу найти ничего подобного уже встроенного. Есть, например, простой и элегантный способ сериализации объекта в JSON в представлениях?
Или я что-то делаю против принципов ASP.NET MVC? Когда я сталкиваюсь с такой проблемой, обычно это заставляет думать, что либо Im делает что-то неправильно, так как я предполагаю, что дизайнеры фреймворка потратили некоторое время на размышления о реальных сценариях мира.
Ответы
Ответ 1
После некоторого времени работы в ASP.NET MVC я пришел к выводу, что (скорее всего) для него нет встроенного помощника. Конечно, тривиально писать свои собственные. Вот он для полноты:
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);
}
}
}
В представлении его можно использовать следующим образом:
<script type="text/javascript">
var page = new Page(<%= Html.Json(new { currentUser: Model.UserName } ) %>);
page.init();
</script>
Ответ 2
В .NET 4 класс HttpUtility имеет множество статических методов кодирования для различных контекстов, включая метод JavaScriptStringEncode
для этого конкретного цель.
Часто проще просто использовать десериализацию JSON.
Ответ 3
В MVC 5 с использованием шаблонов Razor возможно следующее:
<script type="text/javascript">
var page = new Page({ currentUser: @Html.Raw(Json.Encode(Model.UserName)) });
page.init();
</script>
Ответ 4
В моем случае мне нужна строка, а не json-объект, и это для 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);
}
}
Это позволит избежать символов "и конца строки". Также он оставляет числа (int) как число. Это может быть перегружено, чтобы включать поплавок, десятичную и т.д. По мере необходимости.
Итак, мне не нужно думать об этом или делать что-то другое для каждого типа:
var serverName = @ToJS(m.ServerName);
var appSiteUrl = @ToJS(m.SiteUrl);
var facebookId = @ToJS(m.FacebookAppId);