在EpiServer 8中,如何扩展Scheduled Publish事件?

时间:2016-06-14 20:01:30

标签: c# episerver

我正在使用EpiServer 8,并且需要在保存预定发布时执行自定义API调用。目前,我能够通过初始化模块捕获即时发布事件,如下所示:

[InitializableModule]
[ModuleDependency(typeof(EPiServer.Web.InitializationModule))]
public class ContentEventInitializer : IInitializableModule
{
    public void Initialize(InitializationEngine initializationEngine)
    {
        var events = ServiceLocator.Current.GetInstance<IContentEvents>();
        events.PublishingContent += EventsPublishingContent;
    }

    public void Preload(string[] parameters)
    {
    }

    public void Uninitialize(InitializationEngine initializationEngine)
    {
        var events = ServiceLocator.Current.GetInstance<IContentEvents>();
        events.PublishingContent -= EventsPublishingContent;
    }

    private void EventsPublishingContent(object sender, ContentEventArgs contentEventArgs)
    {
        // Tell our API that maintenance started.
    }
}

上述EventsPublishingContent事件在编辑器立即发布内容时有效。该方法的Visual Studio断点成功命中。但是,当网站编辑选择&#34;安排发布时,它不会被执行。&#34;

当编辑正在查看&#34;发布时间表&#34;对话框,并选择&#34; Schedule&#34;按钮,我想捕获以下内容并将其发送到我们的API:

  • &#34;发布&#34;值。
  • 将要发布的网页。

这样做的正确方法是什么?感谢。

2 个答案:

答案 0 :(得分:1)

当使用&#34;计划发布&#34;时,页面将由预定作业发布,我不认为任何事件将由此触发,至少它不会看起来像这样,更多信息在这里:http://world.episerver.com/blogs/Petra-Liljecrantz/Dates/2016/3/differences-between-scheduled-publish-and-normal-publish/

答案 1 :(得分:1)

以下是我运行的解决方案的关键部分。最终,我在IContentEvents的大约12个潜在事件中遇到了突破点,而孤立的2对我的目的非常有用。不幸的是,我不得不从EpiServer数据库中获取预定发布时间戳。提供了代码中的一些TODO注释,这只是为了简化答案。

代码中的备注基于我的观察。我不是EpiServer大师。

using EPiServer;
using EPiServer.Core;
using EPiServer.Framework;
using EPiServer.Framework.Initialization;
using EPiServer.ServiceLocation;

namespace MySite.Helpers
{
    [InitializableModule]
    [ModuleDependency(typeof(EPiServer.Web.InitializationModule))]
    public class ContentEventInitializer : IInitializableModule
    {
        public void Initialize(InitializationEngine initializationEngine)
        {
            var events = ServiceLocator.Current.GetInstance<IContentEvents>();
            events.CheckedInContent += checkedInContent;
            events.PublishedContent += publishedContent;   
        }

        public void Uninitialize(InitializationEngine initializationEngine)
        {
            var events = ServiceLocator.Current.GetInstance<IContentEvents>();
            events.CheckedInContent -= checkedInContent;
            events.PublishedContent -= publishedContent;   
        }

        /// <summary>
        /// Occurs when a version of a content item has been checked in.
        /// </summary>
        /// <remarks>
        /// This is called after a scheduled publish gets saved.  It's not called after an immediate publish.
        /// Useful for executing custom events following a scheduled publish.  When this event occurs,
        /// you can fetch the publish timestamp from dbo.tblWorkContent.DelayPublishUntil.
        /// Prior to this event the DelayPublishUntil value will be NULL.
        /// </remarks>
        public static void checkedInContent(object sender, ContentEventArgs contentEventArgs)
        {
            // Fetch timestamp from dbo.tblWorkContent.DelayPublishUntil.
            ConnectInfo connectInfo = new ConnectInfo("MyEpiServerDatabase");
            PlannedMaintenanceInfo plannedMaintenanceInfo = new PlannedMaintenanceInfo(ref connectInfo, contentEventArgs.Content.ContentLink.WorkID);
            connectInfo = null;
            // The PlannedMaintenanceInfo method above uses the following SQL query:
            //    string query = string.Format("SELECT URLSegment, DelayPublishUntil FROM tblWorkContent WHERE pkId = {0}", WorkID);

            // TODO: Notify API about this planned maintenance window.
        }

        /// <summary>
        /// Occurs when a content item or a version of a content item has been published.
        /// </summary>
        /// <remarks>
        /// This is called after an immediate publish.  It's not called after a scheduled publish gets saved.
        /// Useful for executing custom events following an immediate publish.
        /// </remarks>
        public void publishedContent(object sender, ContentEventArgs contentEventArgs)
        {
            // TODO: Notify API that an immediate maintenance window has started.
        }
    }
}

为简洁起见,省略了数据检索代码和其他运动部件。如果您正在阅读本文,我会假设您知道如何获取数据,并且无论如何都有自己的偏好或框架。我写的实际SQL查询是在checkedInContent方法的注释中。所以你可以把它拿走并在你自己的数据库中运行它。在那里重要的是确保将WorkID传递给查询。该ID来自contentEventArgs.Content.ContentLink.WorkID。

我希望EpiServer公开那个时间戳值,该值最终在表单提交期间保存到tblWorkContent.DelayPublishUntil。这样就没有必要从数据库中获取值。反过来,这将更容易以更通用的方式重用它,我们不需要提供数据库连接字符串来提取该时间戳。如果某个属性中暴露了该值,并且我错过了它,请告诉我。

我希望这段代码可以帮助别人。