复制文档/页面,不包括字段/列或设置新值

时间:2018-04-10 14:31:58

标签: events versioning uniqueidentifier kentico

我正在使用Kentico的第8版,我有一个自定义文档/页面,它有一个唯一的数字标识字段,遗憾的是这个数据来自现有的源码,因为我无法在使用时设置页面耦合数据的主键ID API我被迫拥有这个单独的领域。

如果节点的类名匹配,我确保在使用DocumentEvents.Insert.Before的{​​{1}}事件期间该字段是新的且唯一的。所以我也处理了工作流我也为{{实现了相同的方法1}}。

这在创建新项目时效果很好,无论是否我们尝试复制现有节点,源node.SetValue("ItemIdentifier", newIdentifier);都保持不变。我希望我可以排除该字段被复制,但我还没有找到一个例子。

所以我继续实施了一个解决方案,以确保在通过处理WorkflowEvents.SaveVersion.BeforeIdentifier来复制节点时创建新的标识符。

不幸的是在我的情况下,来自这些事件arg的DocumentEvents.Copy.Before是无用的,我无法为我的生活修改字段,当我打开IlSpy我意识到原因时,节点复制方法抓住了一个新的副本总是来自数据库的节点!因此,如果要在复制节点之前修改字段,则呈现DocumentEvents.Copy.After将无用。

所以我改为在e.Node中传递标识符,使插入进一步在循环中处理,以生成克隆节点的新标识符。

不幸的是,我不知道,如果我们复制一个已发布的节点,那么数据库上的值是正确的,但它的NodeXML值不是。

这个IMO听起来像一个Kentico错误,它要么保留源节点的NodeXML /版本,要么由于某种原因DocumentEvents.Copy.BeforeRequestStockHelper上无法正常工作,因为它是已发布的工作流节点。< / p>

有人遇到类似的问题吗?有没有其他方法我可以将字段配置为唯一的数字标识字段,这不是主键,并在插入时自动递增?或者从复制过程中排除一个字段?

2 个答案:

答案 0 :(得分:1)

作为一种可能的解决方案,您是否可以在DocumentEvents.Copy.Before中创建新文档并从复制的文档中复制值,然后取消复制事件本身?

答案 1 :(得分:0)

好的,事实证明这不是Kentico问题,而是保存版本的方式。

如果要计算DocumentEvents.Insert.Before中的唯一值,则需要将其传递给WorkflowEvents.SaveVersion.Before,因为稍后发送的节点与前者的原始节点相同。例如您在Insert节点中所做的任何更改都不会发送到SaveVersion,您需要手动处理。

所以这里是伪代码处理复制场景并插入编译类型为CineDigitalAV的新项目:

protected override void OnInit()
{
    base.OnInit();

    DocumentEvents.Insert.Before += Insert_Before;
    DocumentEvents.Copy.Before += Copy_Before;
    WorkflowEvents.SaveVersion.Before += SaveVersion_Before;

}

private void Copy_Before(object sender, DocumentEventArgs e)
{
    if (e.Node != null)
    {
        SetCopyCineDigitalIdentifier(e.Node);
    }
}

private void SaveVersion_Before(object sender, WorkflowEventArgs e)
{
    if (e.Document != null)
    {
        EnsureCineDigitalIdentifier(e.Document);
    }
}

private void Insert_Before(object sender, DocumentEventArgs e)
{
    if (e.Node != null)
    {
        EnsureCineDigitalIdentifier(e.Node);
    }
}


private void SetCopyCineDigitalIdentifier(TreeNode node)
{
    int identifier = 0;
    if (node.ClassName == CineDigitalAV.CLASS_NAME)
    {
        identifier = node.GetValue<int>("AVCreation_Identifier", 0);

        // flag next insert to create a new identifier
        if (identifier > 0)
            RequestStockHelper.Add("Copy-Identifier-" + identifier, true);
    }
}


private void EnsureCineDigitalIdentifier(TreeNode node)
{
    int identifier = 0;
    if (node.ClassName == CineDigitalAV.CLASS_NAME)
    {
        identifier = node.GetValue<int>("AVCreation_Identifier", 0);
    }

    if (identifier == 0 || (identifier != 0 && RequestStockHelper.Contains("Copy-Identifier-" + identifier)))
    {
        // generate a new identifier for new items ot those being copied
        RequestStockHelper.Remove("Copy-Identifier-" + identifier);
        int newIdentifier = GetNewCineDigitalIdentifierAV(node.NodeSiteName);
        node.SetValue("AVCreation_Identifier", newIdentifier);

        // store the newidentifier so that saveversion includes it 
        RequestStockHelper.Add("Version-Identifier-" + identifier, newIdentifier);
    }
    else if (RequestStockHelper.Contains("Version-Identifier-" + identifier))
    {
        // handle saveversion with value from the insert
        int newIdentifier = ValidationHelper.GetInteger(RequestStockHelper.GetItem("Version-Identifier-" + identifier), 0);
        RequestStockHelper.Remove("Version-Identifier-" + identifier);

        node.SetValue("AVCreation_Identifier", newIdentifier);
    }
}
private int GetNewCineDigitalIdentifierAV(string siteName)
{
    return (DocumentHelper.GetDocuments<CineDigitalAV>()
                            .OnSite(siteName)
                            .Published(false)
                            .Columns("AVCreation_Identifier")
                            .OrderByDescending("AVCreation_Identifier")
                            .FirstObject?
                            .AVCreation_Identifier ?? 0) + 1;
}