ClientDependency already has full support for MVC...but how do you get it work with the Razor view engine?
Razor and helpers: what’s the deal man?
@Html.HelperA()
@{
Html.HelperB();
}
In the above code, the first example is equivalent to
<%:Html.HelperA() %>
(the HTML escaped version of <%=Html.HelperA() %>) and the second to
<% Html.HelperB() %>
Client “Deep”-endancy
As such, I assumed ClientDependency would look something like this in Razor world:
@{
Html.RequiresCss("Site.css", "Styles");
Html.RequiresJs("Site.js", "Scripts");
}
@Html.RenderCssHere(new List<IClientDependencyPath>() {
new BasicPath("Styles", "/Content/Css")
})
@Html.RenderJsHere(new List<IClientDependencyPath>() {
new BasicPath("Scripts", "/Scripts")
})
Sadly not. I got a compilation error: CS1061: 'System.Web.Mvc.HtmlHelper<object>' does not contain a definition for 'RequiresCss' and no extension method 'RequiresCss' accepting a first argument of type 'System.Web.Mvc.HtmlHelper<object>' could be found (are you missing a using directive or an assembly reference?)
Okay, so I need to include the ClientDependency helpers in the page namespace config. My Web.config (the one in the "Views" folder) turned out looking like this:
<configuration>
<system.web.webpages.razor>
<host factorytype="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<pages pagebasetype="System.Web.Mvc.WebViewPage">
<namespaces>
<add namespace="System.Web.Mvc" />
<add namespace="System.Web.Mvc.Ajax" />
<add namespace="System.Web.Mvc.Html" />
<add namespace="System.Web.Routing" />
<add namespace="ClientDependency.Core" />
<add namespace="ClientDependency.Core.Mvc" />
<add namespace="MySite.Web.Views.Helpers" />
</namespaces>
</pages>
</system.web.webpages.razor>
</configuration>
So I tried running it again, but the @Html.RenderCssHere() and @Html.RenderJsHere() methods had resulted in this
<!--[Css:Name="StandardRenderer"]//-->
<!--[Javascript:Name="StandardRenderer"]//-->
Yuck.
Razor automatically HTML escapes anything returned by a helper when called in the @Html.HelperA() style, unless that helper returns an HtmlString type. Hence the Html.RenderCssHere and Html.RenderJsHere need to be wrapped by an HTML string. Shannon provided this solution in a comment below:
@MvcHtmlString.Create(Html.RenderCssHere(new List<IClientDependencyPath>() {
new BasicPath("Styles", "/Content/Css")
}))
@MvcHtmlString.Create(Html.RenderJsHere(new List<IClientDependencyPath>() {
new BasicPath("Scripts", "/Scripts")
}))
and voila! The best, of the best, of the best.