📜 ⬆️ ⬇️

Serialization of a .NET object in a JavaScript variable on an HTML page inside a Script block

Good old hidden inputs


Often it is necessary to transfer to the HTML page the data that must be used later from JavaScript. It has long been used for this the easiest way: hidden inputs . That is, if we need to pass the address of the web service to Uri, we render something like on the page

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

and we can use jQuery or plain old JavaScript to find this input by name and read the passed value.

But when you need to transfer a lot of parameters or even arrays, this method becomes not convenient. You can of course make a REST service that gives all the data on an AJAX request from the page (session data), but in most cases this is unnecessary.
')
Currently another method is often used - on the server side, to render all the necessary data in HTML as a JavaScript variable inside the Script block.

Consider how to do this in ASP.NET MVC.


The usage scenario will be as follows:

After rendering the page we get a code similar to the following:

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

Extension method for MVC HtmlHelper turned out like this:

  /// <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()); } } 

A few unit tests using the moq framework and 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); } 

Source: https://habr.com/ru/post/163239/


All Articles