XmlForm.Submit() "hides" the validation result message?
I'm using the XmlFormView control on a custom aspx page hosted in a SharePoint site. Recently our SharePoint was upgraded to 2010 and afterwards I've been having problems with the form validation triggered by the XmlForm.Submit().
The custom page is actually relying on the exception thrown by SharePoint, if the validation of the submitted form fails. The validation message is formatted and the shown to the user in a friendly way.
When a form containing an invalid user supplied data is submitted, a "Microsoft.Office.InfoPath.Server.Util.InfoPathFatalException" is returned. This exception doesn't contain information about witch fields contains invalid data. Actually I was expecting an "Microsoft.Office.InfoPath.Server.SolutionLifetime.DataAdapterException". (The submit is successful and no exception is thrown if the form contains no validation errors)
If I uncheck the "Enable Just My Code (Managed only)" option in Visual Studio and debug the form submit, I get the following exception(contains Danish texts):
Microsoft.Office.InfoPath.Server.SolutionLifetime.DataAdapterException occurred Message=Formularen kan ikke afsendes, fordi den indeholder valideringsfejl. Fejlene er angivet 开发者_JAVA百科med en rød stjerne (obligatoriske felter) 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 felter) 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:
This is good! The exception contains information about the validation errors. I Continue the debug. The desired exception is re-thrown and the output reads:
Step into: Stepping over method without symbols 'Microsoft.Office.InfoPath.Server.SolutionLifetime.DatabaseHelper.CheckErrorBoard' Step into: Stepping over method without symbols 'Microsoft.Office.InfoPath.Server.DocumentLifetime.Document.ExecuteDefaultSubmitAction'
This is still good! I continue the debug, but now the original exception is lost and the InfoPathFatalException is returned.
Microsoft.Office.InfoPath.Server.Util.InfoPathFatalException occurred Message=Exception of type 'Microsoft.Office.InfoPath.Server.Util.InfoPathFatalException' was thrown. Source=Microsoft.Office.InfoPath.Server BypassWatson=false SaveUserSession=false UserMessage=Der opstod en alvorlig fejl under behandlingen af formularen. StackTrace: at Microsoft.Office.InfoPath.Server.Util.GlobalStorage.get_CurrentFormId() InnerException:
The VS output now reads:
Step into: Stepping over method without symbols 'Microsoft.Office.InfoPath.Server.SolutionLifetime.DatabaseHelper.CheckErrorBoard' Step into: Stepping over method without symbols 'Microsoft.Office.InfoPath.Server.DocumentLifetime.Document.ExecuteDefaultSubmitAction' Step into: Stepping over method without symbols 'Microsoft.Office.InfoPath.Server.DocumentLifetime.OMExceptionManager.ExecuteOMCallWithExceptions'
I'm quite a novice when it comes to SharePoint, but I think this smells a bit like a security issue? It seems the original exception is not "allowed" to bubble back to the caller.
I've tried to enable full logging in SharePoint, but when I look at the logs in "..\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\LOGS" I can only see the "original" exception, not why it is overwritten?
Additional information: The site currently runs with the config setting:
<trust level="Full" originUrl="" />
Anybody got any ideas about this issue?
On SharePoint 2007 the desired exception is returned back to the caller.
Think this question has been open long enough :-)
The problem was with the way we used the XMLFormView control. Instead of changing our code logic I chose to implement a workaround.
In short: I read this Microsoft documentation: http://msdn.microsoft.com/en-us/library/microsoft.office.infopath.server.controls.xmlformview.xmlform
One of the sections read:
The XmlForm property can only be accessed during one of the following events:
- Initialize
- NotifyHost
- SubmitToHost
- Close
Our code does neither of these!
Basically we do a postback from a standard button on the aspx page, and from the code behind try to call XmlFormView1.XmlForm.Submit();
I found out, using .NET Reflector on the Microsoft.Office.Infopath assembly, that when trying to submit HttpContext.Current.Items["__GlobalStorage.FormIds"] is expected to contain at least one Id form the current form, but at this time it has not yet been set!
So I did the following little “dirty hack” to make the code work again:
/// <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;
}
}
}
}
Anywhere in the code behind, before I try to access XmlFormView1.XmlForm, I just call InfoPath2010Hack();
Not a pretty solution, but it works without changing any other logic.
精彩评论