SPContext.Current.FormContext.OnSaveHandler未从自定义字段类型控件中激发

本文关键字:控件 类型 字段 自定义 FormContext Current OnSaveHandler SPContext | 更新日期: 2023-09-27 18:29:16

我遇到了与此处描述的问题完全相同的问题。不幸的是,因为我还没有50分,我不能对此发表评论,所以我不得不创建一个新的重复问题。

我的意思是,它不像其他人的问题那样"100%准确",因为对我来说,这个问题存在于编辑表单上,我使用的是自定义表单和字段的组合。但我正在根据这个站点上的家伙提出的建议#2,在字段级别添加自定义保存事件处理程序。我还应该注意,当我创建一个没有任何自定义表单或内容类型的新文档库,并且只直接使用我的自定义字段时,事件处理程序也不会启动。但是,如果我创建了一个新的常规SharePoint列表并添加了自定义字段,那么OnSaveHandler就会启动!I所以我不太确定为什么它在文档库中不起作用,但在列表中起作用,因为我觉得自定义字段的美妙之处在于它们独立于其他所有字段运行。这意味着,即使我在编辑表单或其他控件上做了一些不稳定的事情,因为我将自定义方法附加到自定义字段的OnInit方法中的SPContext.Current.FormContext.OnSaveHandler,那么无论怎样,它都应该触发!即使是在第一次加载字段时,我也会在调试器中看到事件的连线。在调试模式下,我在下面的"if"语句旁边有一个断点,它会碰到那个断点,这意味着当触发FormContext.OnSaveHandler时,我的方法应该会激发。

protected override void OnInit(EventArgs e)
{
  base.OnInit(e);
  if ((SPContext.Current.FormContext.FormMode == SPControlMode.New) ||  (SPContext.Current.FormContext.FormMode == SPControlMode.Edit))
    SPContext.Current.FormContext.OnSaveHandler += new EventHandler(MyHandler);
}

有什么想法吗?建议?

谢谢!

更新#1:经过一点故障排除,我能够推断出我的自定义字段中的EventHandler被触发了,但仅当在常规列表NOT文档库中使用时!在常规SharePoint列表中,不仅会激发SPContext.Current.FormContext.OnSaveHandler,还会保存自定义字段中的值。

附带说明一下,当将数据保存回从SPFieldText继承的自定义字段时,该值(即json数据)在列表视图中显示为#value,我觉得这有点奇怪。我的意思是,它能够正确读取存储在字段中的json数据,因为它在编辑表单中显示得很好。但由于某些原因,SharePoint只是将其显示为#VALUE在列表视图中。

SPContext.Current.FormContext.OnSaveHandler未从自定义字段类型控件中激发

因此,在经历了许多令人沮丧的小时之后,在文档库中使用自定义字段时似乎出现了一些问题。

  1. 您不能以任何有意义的方式使用它们,也不能期望在使用自定义上传页面时保存数据。换句话说,如果您想创建自己的自定义上传页面,将文件上传输入字段和浏览按钮与嵌入ListFieldIterator中的自定义字段相结合,则值将不会保存。这是事实!原因是,对于ListItem EventReceiver,上载文件并创建初始ListItem以及生成其ID值的操作发生ASYNCHRONOUSLY。那么这到底意味着什么呢?这意味着,当您尝试访问ListItem的事件接收器中ItemAdded方法的SPItemEventProperties参数中存储在自定义字段中的值时,所有这些值都将为null,因为当前SPContext完全不知道这些字段及其各自值的存在,因为与初始文档上载有关的所有事件在不同的线程中执行。。。异步。相反,当自定义字段试图将自己"保存"回新上传的文档时,SPField.ListItem的文档ID仍然设置为零,因为这些自定义字段是。。。你猜对了,在另一个线程中执行,并且与生成新文档ID的上传事件不"同步"。虽然我读过关于这个问题的一些不同的解决方案,但它们似乎都不起作用,或者它们非常复杂,或者要求你放弃使用自定义字段,这并不是一个真正的解决方法,而是一种"认输"。一个建议是简单地更新EventReceiver的Elements.xml文件,只需添加一个"同步"条目即可强制事件同步而非异步发生。起初,我觉得这太容易了,太好了,不可能是真的。事实证明,我是对的
  2. 不能在自定义控件中嵌套自定义ListFieldIterator,并期望自定义字段保存它们所包含的数据。必须在表单模板中直接使用ListFieldIterator。时期如果您尝试将ListFieldIterator与自定义控件中的自定义字段包装在一起,您将对结果感到非常沮丧

附带说明一下,一旦上传了文档并创建了ID,您就可以CAN在编辑表单中的自定义字段中输入数据,并且值WILL将被保存,因为现在您的代码实际上可以引用ListItem的ID值,因为列表中已经存在ListItem。同样,这与自定义上传表单相反,因为您还没有实际上传文档,所以ListItem的ID还不存在。

我真的希望微软能提供某种更新,让开发人员能够绕过文档库的这个问题,我认为很明显,他们在第一次发布SharePoint时就知道这是一个问题,这就是为什么文档库"新表单"的默认行为是向用户提供一个独立的上传表单,然后重定向用户到编辑表单,这样他们就可以避免所有这些。当然,这让那些希望允许用户在同一屏幕上上传文档和输入数据的开发人员在使用自定义字段时无需站立。你唯一的选择是使用自定义表单,以编程方式设置所有字段值,并为所有不同字段和布局可能性的每一个排列添加大量的条件逻辑,但这完全是另一种动物,当然也违背了微软最初创建自定义字段概念的全部原因!