For a project I'm using jqote for templating in JavaScript and HTML generated by MVC 4 with Razor.
Please have a look at the following code in HTML and Razor:
<script id="testTemplate" type="text/html">
<p>Some html</p>
@{string id = "<%=this.Id%>";}
<!-- 1 -->
@if(true)
{
@Html.Raw(@"<select id="""+id+@"""></select>")
}
<!-- 2 -->
@if(true)
{
<select id="@Html.Raw(id)"></select>
}
<!-- 3 -->
@Html.Raw(@"<select id="""+id+@"""></select>")
<!-- 4 -->
<select id="@Html.Raw(id)"></select>
<!-- 5 -->
<select id="<%=this.Id%>"></select>
</script>
The output is this:
<script id="testTemplate" type="text/html">
<!-- 1 -->
<select id="<%=this.Id%>"></select> <!--Good!-->
<!-- 2 -->
<select id="<%=this.Id%>"></select> <!--BAD!-->
<!-- 3 -->
<select id="<%=this.Id%>"></select> <!--Good!-->
<!-- 4 -->
<select id="<%=this.Id%>"></select> <!--Good!-->
<!-- 5 -->
<select id="<%=this.Id%>"></select> <!--Good!-->
</script>
Now, the problem is with the second select under <!-- 2 -->. One would expect the Html.Raw to kick in here but somehow it doesn't. Or Razor wants to HtmlEncode what's in there.
The question is: Does anyone have an idea why? Is this a bug or by design?
Without the script tags it works. But we need the script tags cause we need to template in JavaScript.
Hardcoded it works, but we need to use a variable because this will not always be a template.
Without the @if it works, but it's there, we need it.
Workarounds
These lines give similar good outputs:
@if(true)
{
<select id= "@Html.Raw(id)"></select>
}
@if(true)
{
<select id ="@Html.Raw(id)"></select>
}
@if(true)
{
<select id @Html.Raw("=")"@Html.Raw(id)"></select>
}
We're planning to do this:
<script id="testTemplate" type="text/html">
@{string id = @"id=""<%=this.Id%>""";}
@if(true)
{
<select @Html.Raw(id)></select>
}
</script>
...to keep as to markup intact as much as possible.