I have following helper
@helper ColectionItemTemplate(object item)
{
<div class="collection-item">
@using (Html.BeginCollectionItem(Html.ViewData.TemplateInfo.HtmlFieldPrefix))
{
@Html.EditorFor(_ => item, null, "")
}
<br class="clear"/>
<a href="#" onclick="$(this).parent().remove(); return false;">Remove</a>
</div>
}
The purpose of this helper is adding collection items on client side by js. I'm using this helper as following
<script type="text/javascript">
(function ($) {
var encodedTemplate = @(Html.Raw(ColectionItemTemplate(editor).ToString().ToJson()));
//Rest of the script
})(jQuery);
</script>
First I call .ToString() to convert HelperResult to it's string representation (withot this .ToJson() will render it as empty object, because HelperResult does not have any public properties)
Then I call .ToJson() to get js-friendly string with tags and some entities encoded.
Then I output it as Raw string, because do not want Razor to encode it again.
But I get corrupted output, because BeginCollectionItem writes index
field directly to the view and not to helper result.
The output
<script type="text/javascript">
(function ($) {
var encodedTemplate = <input type="hidden" name="Items.index" autocomplete="off" value="5cd9e232-5e08-46e2-b84b-31ba4106a978" />
" \u003cdiv class=\"collection-item\"\u003e\n\r\n \u003cdiv class=\"editor-label\"\u003e\r\n \u003clabel for=\"Items_5cd9e232-5e08-46e2-b84b-31ba4106a978__Code\"\u003eC\u003c/label\u003e \r\n \u003c/div\u003e\r\n \u003cdiv class=\"editor-field\"\u003e\r\n \u003cinput class=\"text-box single-line\" data-val=\"true\" data-val-required=\"Code is required\" id=\"Items_5cd9e232-5e08-46e2-b84b-31ba4106a978__Code\" name=\"Items[5cd9e232-5e08-46e2-b84b-31ba4106a978].Code\" type=\"text\" value=\"\" /\u003e \r\n \u003cspan class=\"field-validation-valid\" data-valmsg-for=\"Items[5cd9e232-5e08-46e2-b84b-31ba4106a978].Code\" /*rest sciped*/";
//Rest of the script
})(jQuery);
</script>
As you can see I'm getting index before actual of template and it is not encoded.
And even if I will not output the helper to the view I'll get the input tag in place anyway.
<script type="text/javascript">
(function ($) {
var encodedTemplate = "@{ var x = (Html.Raw(ColectionItemTemplate(editor).ToHtmlString().ToJson())); }";
//Rest of the script
})(jQuery);
</script>
Output
<script type="text/javascript">
(function ($) {
var encodedTemplate = "<input type="hidden" name="Items.index" autocomplete="off" value="e0928e85-6d42-4a27-b4b3-baf5071e9467" />
";
//Rest of the script
})(jQuery);
</script>
The desired output in this case should be var encodedTemplate = "";
but I'm getting the input box, and it is not encoded - error in js.