4

Ok, I got this one working, but I'm not sure about how much of a terrible hack this is. Can anyone tell me if what I did is ok or not, and why?

I needed to share a template between my Razor and JavaScript, so one could use it server-side and the other client-side. So, here is what I did:

Func<dynamic, HelperResult> sampleTemplate =
    @<span>Sample markup @item.Something</span>;

Then, I used my template in my View like this:

for(int idxSample = 0; idxSample < Model.Number; idxSample++) {
    @sampleTemplate(new { Something = "" })
}

And for the javascript I did this:

<script type="text/javascript">
    var someJsTemplate = "" +
        <r><[!CDATA[@sampleTemplate(new { Something = "" })]]></r>;
</script>

So I could later append someJsTemplate whenever I needed it. So, what is the verdict? Does anyone see a better way to do it? Or is this alright?

Edit:

Now I can't use this. Although it works fine in FireFox, Chrome does not allow my hack. Any help?

2 Answers 2

2

Storing HTML in server side code looks like a bad idea to me. Personally I would write a controller:

public class TemplatesController: Controller
{
    [ChildActionOnly]
    public ActionResult Index(Item item)
    {
        return View("~/Views/Shared/EditorTemplates/Item.cshtml", item);
    }
}

and a partial (~/Views/Shared/EditorTemplates/Item.cshtml) containing the markup:

@model AppName.Models.Item
@{
    Layout = null;               
}
<span>Sample markup @Model.Something</span>

Then if I need to use it in a strongly typed view I would simply use an editor template:

@Html.EditorFor(x => x.Items)

and in javascript:

<script type="text/javascript">
    var someJsTemplate = '@HttpUtility.JavaScriptStringEncode(Html.Action("index", "templates", new { something = "abc" }).ToHtmlString())';
</script>

And to simplify a little bit this javascript call you could write a helper:

public static class HtmlExtensions
{
    public static MvcHtmlString Template(this HtmlHelper htmlHelper, object item)
    {
        return MvcHtmlString.Create(
            HttpUtility.JavaScriptStringEncode(
                htmlHelper.Action("index", "templates", item).ToHtmlString()
            )
        );
    }
}

and then:

<script type="text/javascript">
    var someJsTemplate = '@Html.Template(new { something = "abc" })';
</script>
Sign up to request clarification or add additional context in comments.

2 Comments

About storing HTML in server-side, well... it is a Razor view, right? So, it is server-side and it does contain HTML. But about the JavaScriptStringEncode, thanks so much for the tip! What happened is I just wrote a helper that does almost practically what JavaScriptStringEncode does. Could've saved me some time if I had known... Anyway, tank you!
@rdumont, yeah JavaScriptStringEncode is useful and protects you from the bad guys willing to XSS your site :-)
0

That looks good to me. Though I'd suggest investigating @helper syntax, which would only slightly change the usage of the template.

1 Comment

Yes, by defining a helper I could drop that dynamic parameter, it would definitely make the code clearer. But I will only use this template in one single view, therefore I do not know if it is worth it defining a whole helper just to do it. But thanks for the advice! I will certainly consider it.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.