【问题标题】:Help with ASP.NET MVC HtmlHelper API Design帮助 ASP.NET MVC HtmlHelper API 设计
【发布时间】:2010-11-02 00:17:05
【问题描述】:

我正在为 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 的上下文被释放时,所有六个文件都被合并到一个 css 文件中,并作为单个链接标签(或脚本、css sprite 等)写出

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

【问题讨论】:

  • 我不确定这个帮手给你买了什么。这不正是内容占位符的用途吗?
  • @John - 这个想法是每次调用 Html.CompositeCssResourcePart 都将定义复合资源的一部分(即,在释放上下文时将合并到一个文件中)。因此,我需要一种收集所有部分的方法,然后才能呈现链接/脚本标记,因为 URL 是从所有引用的资源生成的。有意义吗?
  • using 在这种情况下是有意义的,但除此之外我无法发表评论。
  • 是的,当然可以。感谢您的澄清。

标签: c# asp.net-mvc


【解决方案1】:

经过深思熟虑(并咨询了一位同事),我觉得最好的选择是坚持我最初的计划,即不使用“部分”资源定义的概念污染我的 ASP.NET MVC API(适用于 WebControls ,但在我看来,MVC 不如 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>

这将使您在组合共享资源时不会重复自己(即确保一致性)并最终处理此案。

我会暂时保持开放状态,看看是否有任何反馈;但除非有充分的理由说明为什么这是不可接受的,否则我认为这就是答案。

【讨论】:

    【解决方案2】:

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

    <%: Html.MergedStyleSheet() %>
    

    可以输出:

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

    【讨论】:

    • 我过去使用过构建任务,这绝对是一种选择。我认为运行时方法的主要优点是您几乎可以像往常一样在每个页面中定义资源,并且可以轻松地在缩小/组合和调试模式之间切换,而无需额外的努力;您也不必担心维护构建任务或版本控制问题等。此外,当我处理 CSS Sprites 时,我个人喜欢直接在使用它的页面中查看 sprite 定义。我的兴趣是针对我尚未涵盖的上述场景提出的 API。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-31
    • 2011-08-17
    • 1970-01-01
    • 2015-04-07
    • 2014-06-04
    相关资源
    最近更新 更多