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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.