0

我在 SharePoint 网站中托管的自定义 aspx 页面上使用 XmlFormView 控件。最近我们的 SharePoint 升级到 2010,之后我遇到了由 XmlForm.Submit() 触发的表单验证问题。

如果提交的表单验证失败,自定义页面实际上依赖于 SharePoint 引发的异常。验证消息经过格式化并以友好的方式显示给用户。

提交包含无效用户提供数据的表单时,将返回“Microsoft.Office.InfoPath.Server.Util.InfoPathFatalException”。此异常不包含有关女巫字段包含无效数据的信息。实际上我期待“Microsoft.Office.InfoPath.Server.SolutionLifetime.DataAdapterException”。(如果表单不包含验证错误,则提交成功,不抛出异常)

如果我取消选中 Visual Studio 中的“仅启用我的代码(仅限托管)”选项并调试表单提交,我会收到以下异常(包含丹麦文本):

Microsoft.Office.InfoPath.Server.SolutionLifetime.DataAdapterException 发生
Message=Formularen kan ikke afsendes, fordi den indeholder valideringsfejl。Fejlene er angivet med en rød stjerne (obligatoriske feeler) eller omgivet af en rød, stiplet streg (ugyldige værdier)。

Felt eller gruppe: MunicipalRealPropertyIdentifier
Fejl: Der må kun angives et bestemt mønster

Source=Microsoft.Office.InfoPath.Server
BypassWatson=true
LogId=5567
SaveUserSession=false
UserMessage=Formularen kan ikke afsendes, fordi den indeholder valideringsfejl。Fejlene er angivet med en rød stjerne (obligatoriske feeler) eller omgivet af en rød, stiplet streg (ugyldige værdier)。

Felt eller gruppe:MunicipalRealPropertyIdentifier
Fejl: Der må kun angives et bestemt mønster

OverrideTopLevelMessage=true
StackTrace:
at
Microsoft.Office.InfoPath.Server.SolutionLifetime.DatabaseHelper.CheckErrorBoard(Document document, DataAdapter adapter, XPathNavigator subtreeToCheck, Boolean schemaErrorOnly)
InnerException:

这很好!异常包含有关验证错误的信息。我继续调试。重新抛出所需的异常,输出内容为:

步入:跳过不带符号“Microsoft.Office.InfoPath.Server.SolutionLifetime.DatabaseHelper.CheckErrorBoard”的方法 步入:跳过不带符号“Microsoft.Office.InfoPath.Server.DocumentLifetime.Document.ExecuteDefaultSubmitAction”的方法

这个还是不错的!我继续调试,但现在原始异常丢失并返回 InfoPathFatalException。

发生 Microsoft.Office.InfoPath.Server.Util.InfoPathFatalException
消息 = 引发“Microsoft.Office.InfoPath.Server.Util.InfoPathFatalException”类型的异常。
Source=Microsoft.Office.InfoPath.Server
BypassWatson=false
SaveUserSession=false
UserMessage=Der opstod en alvorlig fejl under behandlingen af formularen。
StackTrace:
在 Microsoft.Office.InfoPath.Server.Util.GlobalStorage.get_CurrentFormId()
InnerException:

VS 输出现在显示为:

步入:跳过不带符号“Microsoft.Office.InfoPath.Server.SolutionLifetime.DatabaseHelper.CheckErrorBoard”的方法 步入:跳过不带符号“Microsoft.Office.InfoPath.Server.DocumentLifetime.Document.ExecuteDefaultSubmitAction”的方法 步入:步入没有符号'Microsoft.Office.InfoPath.Server.DocumentLifetime.OMExceptionManager.ExecuteOMCallWithExceptions'的方法

对于 SharePoint,我是个新手,但我认为这听起来有点像安全问题?似乎原始异常不是“允许”返回给调用者的。

我尝试在 SharePoint 中启用完整日志记录,但是当我查看“..\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\LOGS”中的日志时,我只能看到“原始”异常,不是为什么它被覆盖?

附加信息:该站点当前使用配置设置运行:

<trust level="Full" originUrl="" />

有人对这个问题有任何想法吗?

在 SharePoint 2007 上,所需的异常将返回给调用者。

4

1 回答 1

1

认为这个问题已经开放了足够长的时间:-)

问题在于我们使用 XMLFormView 控件的方式。我没有改变我们的代码逻辑,而是选择了一种解决方法。

简而言之:我阅读了此 Microsoft 文档:http: //msdn.microsoft.com/en-us/library/microsoft.office.infopath.server.controls.xmlformview.xmlform

其中一节内容如下:

XmlForm 属性只能在以下事件之一期间访问:

  • 初始化
  • 通知主机
  • 提交给主机

我们的代码都不做这些!

基本上,我们从 aspx 页面上的标准按钮进行回发,并从后面的代码尝试调用 XmlFormView1.XmlForm.Submit();

我发现,在 Microsoft.Office.Infopath 程序集上使用 .NET Reflector,当尝试提交HttpContext.Current.Items["__GlobalStorage.FormIds"]时,预计至少包含一个当前表单的 Id,但在此时间还没有确定!

所以我做了以下小“肮脏的黑客”来使代码再次工作:

        /// <summary>
    /// Dirty hack to fix issue after update to InfoPath 2010 
    /// </summary>
    private static void InfoPath2010Hack()
    {
        if (HttpContext.Current != null)
        {
            if (HttpContext.Current.Items["__GlobalStorage.FormIds"] == null)
            {
                var formIds = new Stack<string>();
                formIds.Push("XmlFormView1");
                HttpContext.Current.Items["__GlobalStorage.FormIds"] = formIds;
            }
            else
            {
                var formIds = ((Stack<string>)HttpContext.Current.Items["__GlobalStorage.FormIds"]);
                if (formIds.Count <= 0)
                {
                    formIds.Push("XmlFormView1");
                    HttpContext.Current.Items["__GlobalStorage.FormIds"] = formIds;
                }
            }
        }
    }

在代码后面的任何地方,在我尝试访问 XmlFormView1.XmlForm 之前,我只需调用 InfoPath2010Hack();

这不是一个漂亮的解决方案,但它可以在不改变任何其他逻辑的情况下工作。

于 2012-06-21T06:58:25.657 回答