Создание событий и управление версиями .js и .css файлов - PullRequest
1 голос
/ 02 октября 2009

У меня настроен скрипт MSBuild для минимизации и объединения моих javascript и css файлов. Что мне сейчас нужно, так это способ их версии. Как вы, ребята, в настоящее время справляетесь с этим. Каков наилучший способ постепенного создания версий файла и обновления тега <script/> новым именем файла?

1 Ответ

0 голосов
/ 03 октября 2009

Первоначально я собирался предложить использовать выражения ресурсов для включения тега версии из AppSettings, но после тестирования обнаружил, что он работает, только если это полное значение свойства элемента управления сервером.

Значение AppSettings может обновляться сценарием сборки для каждого выпуска; может быть любого формата, который вам нравится:

<appSettings>
 <add key="versionTag" value="27" />
</appSettings>

Работает:

<asp:Label runat="server" Text="<%$ AppSettings: versionTag %>" />

Не работает:

<link runat="server" rel="Stylesheet" type="text/css"
      href='/css/site.css?v=<%$ AppSettings: versionTag %>' />

Так что моя реальная рекомендация - создать свои собственные элементы управления, которые читают тег версии и включают его в свой вывод. Вот как выглядит мой CSS-элемент управления на странице (ПРИМЕЧАНИЕ: серверные элементы управления должны находиться внутри серверной формы, даже если они могут отображаться внутри элемента head):

...
<form id="form1" runat="server">
 <my:Stylesheet runat="server" Url="~/css/site.css" />
</form>
...

Код для моего элемента управления таблицей стилей:

namespace MyNamespace
{
    using System;
    using System.ComponentModel;
    using System.Configuration;
    using System.Security.Permissions;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.HtmlControls;
    using System.Web.UI.WebControls;

    /// <summary>
    /// Outputs a CSS stylesheet link that supports versionable caching via a
    /// build-specific query parameter.
    /// </summary>
    [
        AspNetHostingPermission(SecurityAction.InheritanceDemand,
                Level = AspNetHostingPermissionLevel.Minimal),
        AspNetHostingPermission(SecurityAction.LinkDemand,
                Level = AspNetHostingPermissionLevel.Minimal),
        DefaultProperty("Href"),
        ToolboxData(@"<{0}:Stylesheet runat=""server"" />")
    ]
    public class Stylesheet : WebControl
    {
        private static string versionTag = Stylesheet.GetVersionTag();

        /// <summary>
        /// Gets or sets the stylesheet URL.
        /// </summary>
        public string Href
        {
            get
            {
                return this.ViewState["Href"] as string;
            }

            set
            {
                this.ViewState["Href"] = value;
            }
        }

        /// <summary>
        /// Raises the PreRender event.
        /// </summary>
        /// <param name="e">Contains the event data.</param>
        protected override void OnPreRender(EventArgs e)
        {
            base.OnPreRender(e);

            HtmlLink link = new HtmlLink();
            link.Href = String.Format(
                    "{0}?v={1}",
                    this.Page.ResolveUrl(this.Href),
                    HttpUtility.UrlEncode(Stylesheet.versionTag));

            if (!Stylesheet.HeadContainsLinkHref(this.Page, link.Href))
            {
                link.Attributes["type"] = "text/css";
                link.Attributes["rel"] = "Stylesheet";
                this.Page.Header.Controls.Add(link);
            }
        }

        /// <summary>
        /// Generates content to be rendered on the client.
        /// </summary>
        /// <param name="writer">Receives the server control content.</param>
        protected override void Render(HtmlTextWriter writer)
        {
            // Do nothing.
        }

        /// <summary>
        /// Retrieves the script version tag for this build.
        /// </summary>
        /// <returns>Returns the script version tag.</returns>
        private static string GetVersionTag()
        {
            string tag = ConfigurationManager.AppSettings["versionTag"];
            if (String.IsNullOrEmpty(tag))
            {
                tag = "1";
            }

            return tag;
        }

        /// <summary>
        /// Determines if the page's <c>head</c> contains a <c>link</c> tag
        /// with a matching <c>href</c> attribute value.
        /// </summary>
        /// <param name="thePage">The Page to be tested.</param>
        /// <param name="href">The <c>href</c> URL to be matched.</param>
        /// <returns>Returns true if a matching link is already part of the
        /// page <c>head</c> or false otherwise.</returns>
        public static bool HeadContainsLinkHref(Page thePage, string href)
        {
            if (thePage == null)
            {
                throw new ArgumentNullException("thePage");
            }

            foreach (Control control in thePage.Header.Controls)
            {
                if ((control is HtmlLink) &&
                    (control as HtmlLink).Href == href)
                {
                    return true;
                }
            }

            return false;
        }
    }
}

НТН.

...