代码之家  ›  专栏  ›  技术社区  ›  Toni Frankola

使用Vista时无法更新itemAdded事件的文档属性

  •  2
  • Toni Frankola  · 技术社区  · 15 年前

    我们正在尝试创建一个自定义事件处理程序,该处理程序将在itemadded事件上激发。然后,事件处理程序将具有唯一ID值的文档更新到此文档库中的列。

    我们的解决方案工作正常,除非Vista上的用户试图从Office2007中保存新文档。在此方案中,文档存储到文档库,但唯一ID列为空,没有异常。

    Vista用户可以将文档上载到库中而不会出现问题。在xp和win2k3操作系统上,其他一切都可以正常工作。

    有人看到类似的东西吗?这里可能有什么问题?为了演示这个问题,我们使用了datetime.now作为唯一的ID。

     using Microsoft.SharePoint;
    
     public class TestReciever : SPItemEventReceiver
     {
    
         public override void ItemAdded(Microsoft.SharePoint.SPItemEventProperties properties)
         {
    
             try {
                 DisableEventFiring();
    
                 properties.ListItem("UniqueID Column") = DateTime.Now.ToString();
                 properties.ListItem.SystemUpdate();
    
                 EnableEventFiring();
             }
             catch (Exception ex) {
                 // handle exception
             }
    
    
         }
     }
    
    3 回复  |  直到 14 年前
        1
  •  1
  •   Nat    15 年前

    我们注意到同样的事情发生了。将2007文档添加到库中时,列表中的属性将添加到库中(空白)。

    然后调用(同步)事件处理程序,用uniqueid列的正确值更新列表。

    然后,到2007文档的inbuilt属性映射将开始并用存储在2007文档中的值覆盖您的值(不再引发项目更新事件)。

    这意味着列表中的列现在为空。

    如果您更改为异步事件,您可能会看到我们所做的,并且异步的轻微延迟意味着首先发生到2007文档的属性映射(我们认为),这意味着该值已正确存储。

    可以打破列表和Office之间的属性映射,但这只是一个解决方法。

    我一辈子都找不到这个信息在微软网站上的位置,但这是一个已知的问题。也许你可以把sp2挂在那里(甚至可以在sp1中修复,但我不确定)。

        2
  •  1
  •   Toni Frankola    15 年前

    最后,我们联系了微软,他们为我们提供了以下解决方案。这里的关键是在单独的线程中延迟项目更新。

    private Guid listID;
    private Guid itemID;
    private Guid siteID;
    
    
    
    public override void ItemAdded(Microsoft.SharePoint.SPItemEventProperties properties)
    {
        DisableEventFiring();
    
        item = properties.ListItem;
        listID = properties.ListId;
        itemID = properties.ListItem.UniqueId;
        siteID = properties.SiteId;
    
        Threading.Thread setDocumentInternalIDThread = new Threading.Thread(SetInternalID);
        setDocumentInternalIDThread.Start();
    
    
        EnableEventFiring();
    }
    
    
    private void SetInternalID()
    {
        try {
    
            Threading.Thread.Sleep(10000);
            using (SPSite site = new SPSite(siteID)) {
                using (SPWeb web = site.OpenWeb()) {
    
                    SPList list = web.Lists(listID);
                    SPListItem item = list.Items(itemID);
    
                    item(Common.CustomID) = Common.GetAlphaPrefix() + Common.GetDocNumber();
                    item.SystemUpdate();
                }
    
            }
        }
        catch (Exception ex) {
    
            Log(ex.Message);
        }
    }
    
        3
  •  0
  •   Wade Hunter    15 年前

    另一个解决方法是将事件接收器中正在更新的自定义字段设置为只读(将Fields ReadOnly属性设置为true)。这有一些利弊。这是唯一ID解决方案的理想选择,因为用户无法修改该值。但是,该字段对用户界面是隐藏的,因此管理它会变得更麻烦,而且该字段不能用于标签或快速部件中。可以将字段的ShowInPlayForm属性设置为true,以便在视图窗体中显示字段,而不是在编辑窗体中显示字段。该字段也可以添加到视图中。这是迄今为止我为这个问题找到的最佳解决方案。

    这是Office2007和WSS3.0XML解析器的问题。当属性从Office2007文档升级时,解析器尝试将文档属性分配给SharePoint中的列表属性(属性升级)。问题是,此事件发生在任何itemAdded或itemUpdated事件之后,因此属性将被文档中的值覆盖,当然,该值为空。微软把这个当成了一个bug,我希望能在sp2中找到一个修复方法,但没有这样的运气。