开发者

Help with ASP.NET MVC HtmlHelper API Design

I am working on a runtime composite resource library for ASP.NET WebForms/MVC. I support both standard ASP.NET WebForms via WebControls and have also recently added support for ASP MVC Html Helpers. One feature that I currently support with the WebForms WebControls is the concept of "Partial" resource definitions where a resource can be combined over the Master/View pages etc.

When implementing the MVC equivalent, I am not sure what the best practise is? I am currently leaning towards a design something like:

Master Page

<% using (Html.CreateCompositeResourcePartContext())
   {
     Html.CompositeCssResourcePart(
       "ResourceName", 
       new[] { "/Styles/SharedStyle1.css", "/Styles/SharedStyle2.css" }
     );
     %>
    <asp:ContentPlaceHolder ID="head" runat="server">
    </asp:ContentPlaceHolder>
<% } %>

Which will create a "context" wrapper around the head ContentPlaceholder.

View Page

<asp:Content ID="HeadContentPlaceholder" ContentPlaceHolderID="head" runat="server">
  <% Html.CompositeCssResourcePart(
     "ResourceName", 
     new[] 
     {
       "/Styles/PageStyle5.css",
       "/Styles/PageStyle6.css",
       "/Styles/PageStyle7.css"
     }) %>
</asp:Content>

So any view pages can extend the partial resource definition as seen above.

The questions I have:

1) Unlike all my other HtmlHelpers, these extensions do not immediately write out the HTML fragment but rather wait until the context is disposed. Should these extensions be off the ViewContext instead (or some other object)?

2) I personally think the concept of a "using" makes sense to wrap a block of code rather than separate BeginCompositeResourcePartContext/EndCompositeResourcePartContext calls, would you agree? If no, what is better about separate method calls?

Any feedback on the above would be greatly appreciated. If more detail is required, please let me know.

Edit

To clarify... the block inside the head of the Master page and the subsequent reference in si开发者_如何转开发de a view page will be combined together in to a single resource. So when the context of CompositeResourcePartContext is disposed, all SIX files are combined in to only ONE css file and written out as a single link TAG (or script, css sprite etc)

<link rel="stylesheet" type="text/css" href="/MyMergedStyleSheet.css" />


After giving it some more thought (and consulting a colleague) I feel that the best option is to stick with my original plan of not polluting my ASP.NET MVC API with the concept of "partial" resource definitions (works for WebControls, but not as nice with MVC in my opinion). Prior to considering an explicit HtmlHelper extension for this case in my library, I suggested that the issue can be handled by defining a custom extension method as follows:

public static class CustomXpediteExtensions
{
    private static readonly IEnumerable<String> SharedCss = new[]
    {
        "/Styles/SharedStyle1.css",
        "/Styles/SharedStyle2.css",
        "/Styles/SharedStyle3.css"
    };

    public static MvcHtmlString CustomCompositeCssResource(this HtmlHelper htmlHelper, params String[] resources)
    {
        return htmlHelper.CompositeCssResource(SharedCss.Concat(resources));
    }
}

And then simply referencing that custom extension (or constant, etc.) in the view page.

<asp:Content ID="Content2" ContentPlaceHolderID="head" runat="server">
  <%= Html.CustomCompositeCssResource(
        "/Styles/PageStyle5.css",
        "/Styles/PageStyle6.css",
        "/Styles/PageStyle7.css"
      ) %>
</asp:Content>

This will allow you to not repeat yourself when combining shared resources (i.e., ensuring consistency) and ultimately handle the case.

I will leave this open for a while to see if there is any feedback on this; but unless a good case is made for why this is not acceptable, I think it is the answer.


It seems like a great idea, but it might be better served as a part of the build process. You could easily create merged CSS for individual pages using a T4 template, and perhaps a naming convention for adding that CSS reference to your page. Something like:

<%: Html.MergedStyleSheet() %>

could output:

<link rel="stylesheet" type="text/css" href="/Content/ControllerName/ActionName.css" />
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜