如何在ASP.NET MVC局部视图(服务器端)中注入CSS文件?

9
我有一个部分视图(.ascx),它应该包含自己的CSS文件,因为它在多个其他视图中使用。我如何在服务器端注入样式表,即不使用JavaScript的方法?

我认为在这里使用的一个好技巧是确保即使在多次引用该部分时,也不要重复链接样式表。 - Drew Noakes
为什么你不能在局部的开头包含对样式表的引用? - Justin Soliz
@Justin 因为它不是有效的XHTML。 - Dario Solera
5个回答

2
Dario - 由于您在使用这个partialviews功能时,会一直面临一个问题,即文档的部分已经存在,因此无法进行修改。如果您想保持WC3的兼容性,则需要通过JavaScript将任何进一步的CSS放入head部分中。这可能是可取的(如果你必须为关闭javascript的下游浏览器提供服务)。
您所提到的主要问题可能是您不能将放入partials中。这是一个繁琐的事情(尽管可以理解,因为MasterPage参考将Partial与特定的Master Page过于紧密地联系在一起)。
为此,我创建了一个小helper方法,自动将css文件放入head部分,并执行基本grunt工作。
编辑-(根据Omu的js建议)这是一个不错的半途而废的房子:
// standard method - renders as defined in as(cp)x file
public static string Css(this HtmlHelper html, string path)
{
    return html.Css(path, false);
}
// override - to allow javascript to put css in head
public static string Css(this HtmlHelper html, string path, bool renderAsAjax)
{
    var filePath = VirtualPathUtility.ToAbsolute(path);

    HttpContextBase context = html.ViewContext.HttpContext;
    // don't add the file if it's already there
    if (context.Items.Contains(filePath))
        return "";

    // otherwise, add it to the context and put on page
    // this of course only works for items going in via the current
    // request and by this method
    context.Items.Add(filePath, filePath);

    // js and css function strings
    const string jsHead = "<script  type='text/javascript'>";
    const string jsFoot = "</script>";
    const string jsFunctionStt = "$(function(){";
    const string jsFunctionEnd = "});";
    string linkText = string.Format("<link rel=\"stylesheet\" type=\"text/css\" href=\"{0}\"></link>", filePath);
    string jsBody = string.Format("$('head').prepend('{0}');", linkText);

    var sb = new StringBuilder();

    if (renderAsAjax)
    {
        // join it all up now
        sb.Append(jsHead);
        sb.AppendFormat("\r\n\t");
        sb.Append(jsFunctionStt);
        sb.AppendFormat("\r\n\t\t");
        sb.Append(jsBody);
        sb.AppendFormat("\r\n\t");
        sb.Append(jsFunctionEnd);
        sb.AppendFormat("\r\n");
        sb.Append(jsFoot);
    } 
    else
    {
        sb.Append(linkText);
    }

    return sb.ToString();
}

用法:

<%=Html.Css("~/Content/yourstyle.Css")%>

或者:

<%=Html.Css("~/Content/yourstyle.Css", true)%> // or false if you want!!

如果一切都失败了,这种方法就值得尝试。还有可能根据上述逻辑来击中一个ActionFilter,并将CSS添加到响应头中等等,而不是输出JS字符串。


顺便说一句,我发现了这篇文章,它添加了一些代码,让您可以这样做:http://somewebguy.wordpress.com/2010/04/06/adding-stylesheets-scripts-in-asp-net-mvc2/,然后跟随链接 http://gist.github.com/358458 - jim tollan

1

我不是ASP.NET或MVC专家,但我目前正在使用它进行项目开发。在您的母版页头部分是否可以包含类似以下内容?

<asp:ContentPlaceHolder ID="HeadContent" runat="server"></asp:ContentPlaceHolder>

然后如何将您的CSS放入内容占位符中呢?

<asp:Content ID="styleSheetHolder" ContentPlaceHolderID="HeadContent" runat="server">
  <link rel='stylesheet' href='yourstyle.css' type='text/css' />
</asp:Content>

看起来你需要从调用页面做这件事,这将引入重复的代码。我不确定如何避免这个问题。也许可以使用 HTML 助手来完成它。


你必须有意识地在部分视图之外(即在页面中)执行此操作。如果有一种解决方案可以在部分视图内工作,那将是很好的,因为这些情况下它们是有条件包含的。 - Drew Noakes

1

你不能把样式表放在主视图页面中吗?除非它非常大,否则即使在未使用时,它也不应该导致页面加载明显变慢,尤其是在压缩后。

此外,如果通过ajax检索部分视图,则将多次重新下载css文件(取决于浏览器的缓存)。


我希望我的部分视图是自包含的(此外,它是在服务器端呈现的,而不是通过 AJAX 加载)。 - Dario Solera

0
为什么不在你的部分视图中放置链接标签呢?
<link rel="stylesheet" href="yourstyle.css" type="text/css" />

这使得文档无效。 - Dario Solera
我猜测 HTML 验证器使其无效了。但我确定浏览器正在正确地渲染。我没有在规范中看到它只能在 head 标签内的说明。 - ajay_whiz

0
我曾经工作的一个地方有一个网站,其中有很多有条件的部分视图,随着应用程序中添加新内容,这些部分视图可能会发生更改。我们发现最好的方法是使用命名约定-将局部视图、样式表和脚本命名相同(当然不包括扩展名)。
我们向页面的视图模型添加了一个或多个样式表、脚本和局部视图。然后,我们使用自定义的 HTML 助手循环遍历每个内容部分中的相关数组,并插入所需的内容。痛苦的是要为每个组件管理三个或更多文件,但至少我们能够减少托管页面的维护量。
尽管如此,我们从来没有解决过将部分视图放置在另一部分视图内的问题。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接