Сериализация Объекта .Net В Переменную Javascript На Странице Html Внутри Блока Script.



Старые добрые скрытые входы Часто вам необходимо передать данные в HTML-страницу, которую затем необходимо использовать из JavaScript. Для этого уже давно используется самый простой метод: скрытые входы .

То есть, если нам нужно передать адрес Uri веб-службы, мы отображаем что-то вроде

  
  
  
   

<input type="hidden" name="webServiceUri" value="URI we need"/>

и используя jQuery или старый добрый JavaScript, мы можем найти этот ввод по имени и прочитать переданное значение.

Но когда вам нужно передать много параметров или даже массивов, этот метод становится неудобным.

Можно, конечно, сделать REST-сервис, возвращающий все данные через AJAX-запрос со страницы (данные сессии), но в большинстве случаев в этом нет необходимости.

В настоящее время часто используется другой метод — на стороне сервера визуализировать все необходимые данные в HTML в виде переменной JavaScript внутри блока Script.

Давайте посмотрим, как это сделать в ASP.NET MVC.

Сценарий использования будет таким:
  • у нас есть класс .

    NET, который инкапсулирует необходимые настройки, и мы можем использовать для этого любой класс

  • у нас есть метод расширения для MVC HtmlHelper, который принимает имя переменной JavaScript и объекта, который необходимо сериализовать.

  • сериализуемый класс передается представлению внутри ViewModel или ViewBag
  • имя переменной JavaScript может быть передано в представление из контроллера или жестко закодировано в представлении.

После рендеринга страницы мы получаем код, подобный следующему:

<script type="text/javascript"> var settings = {"WebServiceUri":"URI we need","UserId":"1212"}; </script>

Метод расширения для MVC HtmlHelper получился таким:

/// <summary> /// This class provides the extension methods to ASP.NET MVC HtmlHelper. /// </summary> public static class HtmlHelperExtensions { /// <summary> /// This method renders the given model class as JavaScript variable within Html Script tag. /// </summary> /// <param name="htmlHelper">HtmlHelper instance we extend by this method.</param> /// <param name="variableName">The name of JavaScript variable the rendered Json object will be assigned to.</param> /// <param name="model">The model class to be rendered to Json and assigned to the variable.</param> /// <returns>Html representation of Html Script tag.</returns> public static MvcHtmlString RenderJsToScriptBlock(this HtmlHelper htmlHelper, string variableName, object model) { #region Pre-conditions if (string.IsNullOrWhiteSpace(variableName)) { throw new ArgumentNullException("variableName"); } #endregion Pre-conditions if (null == model) { return MvcHtmlString.Empty; } TagBuilder tagBuilder = new TagBuilder(@"script"); tagBuilder.MergeAttribute(@"type", @"text/javascript"); // use InnerHtml because it doesn't encode characters tagBuilder.InnerHtml = string.Format("var {0} = {1};", variableName, htmlHelper.Raw(Json.Encode(model))); return new MvcHtmlString(tagBuilder.ToString()); } }

Некоторые модульные тесты с использованием структуры moq и MSTest:

[TestMethod, TestCategory("Unit")] [ExpectedException(typeof(ArgumentNullException))] public void Should_Not_Accept_Null_VariableName() { HtmlHelper helper = new HtmlHelper(new Mock<ViewContext>().

Object, new Mock<IViewDataContainer>().

Object); helper.RenderJsToScriptBlock(null, null); } [TestMethod, TestCategory("Unit")] [ExpectedException(typeof(ArgumentNullException))] public void Should_Not_Accept_Empty_VariableName() { HtmlHelper helper = new HtmlHelper(new Mock<ViewContext>().

Object, new Mock<IViewDataContainer>().

Object); helper.RenderJsToScriptBlock(string.Empty, null); } [TestMethod, TestCategory("Unit")] public void Should_Return_Empty_MvcHtmlString_For_NullModel() { HtmlHelper helper = new HtmlHelper(new Mock<ViewContext>().

Object, new Mock<IViewDataContainer>().

Object); MvcHtmlString mvcHtmlString = helper.RenderJsToScriptBlock("variableName", null); Assert.AreEqual(mvcHtmlString, MvcHtmlString.Empty); } [TestMethod, TestCategory("Unit")] public void Should_Return_Correct_Result_For_Correct_Input() { const string expectedHtmlString = "<script type=\"text/javascript\">var variableName = {\"UserName\":\"Alex\"};</script>"; HtmlHelper helper = new HtmlHelper(new Mock<ViewContext>().

Object, new Mock<IViewDataContainer>().

Object); var model = new { UserName = "Alex" }; MvcHtmlString mvcHtmlString = helper.RenderJsToScriptBlock("variableName", model); Assert.AreEqual(mvcHtmlString.ToHtmlString(), expectedHtmlString); }

Теги: #ASP.NET #asp.net mvc 4 #Разработка веб-сайтов #.

NET #C++

Вместе с данным постом часто просматривают: