帮助ASP.NET MVC HtmlHelper API设计

时间:2010-11-02 00:17:05

标签: c# asp.net-mvc

我正在为ASP.NET WebForms / MVC开发运行时复合资源库。我通过WebControls支持标准的ASP.NET WebForms,并且最近还添加了对ASP MVC Html Helpers的支持。我目前支持WebForms WebControls的一个功能是“部分”资源定义的概念,其中资源可以通过主/视图页面等组合。

在实现MVC等价物时,我不确定最佳做法是什么?我目前倾向于设计类似于:

母版页

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

这会在头部ContentPlaceholder周围创建一个“上下文”包装器。

查看页面

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

因此,任何视图页面都可以扩展部分资源定义,如上所示。

我的问题:

1)与我的所有其他HtmlHelper不同,这些扩展不会立即写出HTML片段,而是等到处理上下文。这些扩展是否应该取决于ViewContext(或其他一些对象)?

2)我个人认为“使用”的概念包含一段代码而不是单独的BeginCompositeResourcePartContext / EndCompositeResourcePartContext调用是否合理?你同意吗?如果不是,那么单独的方法调用有什么好处呢?

对此有任何反馈意见将不胜感激。如果需要更多详细信息,请告知我们。

修改

为了澄清......主页面头部内的块和视图页面中的后续引用将被合并到一个资源中。所以当处理CompositeResourcePartContext的上下文时,所有SIX文件只被合并到一个css文件中并写成单个链接TAG(或脚本,css sprite等)

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

2 个答案:

答案 0 :(得分:4)

在给予更多考虑(并咨询同事)之后,我认为最好的选择是坚持我的原始计划,即不使用“部分”资源定义的概念污染我的ASP.NET MVC API(适用于WebControls) ,但在我看来,并不像MVC那么好。在我的库中为此案例考虑明确的HtmlHelper扩展之前,我建议可以通过定义自定义扩展方法来处理该问题,如下所示:

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));
    }
}

然后在视图页面中简单地引用该自定义扩展(或常量等)。

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

这将允许您在组合共享资源时不重复(即确保一致性)并最终处理案例。

我会暂时搁置一下,看看是否有任何反馈意见;但除非有一个好的案例说明为什么这是不可接受的,我认为这就是答案。

答案 1 :(得分:2)

这似乎是一个好主意,但它可能更适合作为构建过程的一部分。您可以使用T4模板轻松地为单个页面创建合并的CSS,也可以使用命名约定将CSS引用添加到页面。类似的东西:

<%: Html.MergedStyleSheet() %>

可以输出:

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