InfoPath Forms Services and the xsi:nil in code behind


October 25, 2013 - 12:27, by Steven Van de Craen - 1 Comments

Yesterday I had the requirement to programmatically add and remove the xsi:nil attribute from an InfoPath 2010 browser form hosted in InfoPath Forms Services in SharePoint 2010.

There are several solutions for adding and removing xsi:nil to be found on the internet, but I’ve found only one that works in both browser and InfoPath client forms, and that’s by replacing the node’s OuterXml.

public const string NIL_PREFIX = "xsi";
public const string NIL_LOCALNAME = "nil";
public const string NIL_NAMESPACE = "http://www.w3.org/2001/XMLSchema-instance";
        
public static void RemoveNil(XPathNavigator node)
{
    if (node.MoveToAttribute(NIL_LOCALNAME, NIL_NAMESPACE))
        node.DeleteSelf();
}

public static void ClearAndSetNil(XPathNavigator node)
{
    XmlDocument doc = new XmlDocument();
    doc.LoadXml(node.OuterXml);

    XmlElement nDoc = doc.DocumentElement;

    XmlAttribute attr = doc.CreateAttribute(NIL_PREFIX, NIL_LOCALNAME, NIL_NAMESPACE);
    attr.Value = BoolHelper.True;

    nDoc.Attributes.Append(attr);
    nDoc.InnerText = String.Empty;

    node.ReplaceSelf(nDoc.OuterXml);
}

All other solutions seem to throw the “Schema validation found non-data type errors” error. Note that the xsi:nil attribute is only required for field types that require a value, such as:

  • Whole Number (integer)
  • Decimal (double)
  • Date (date)
  • Time (time)
  • Date and Time (dateTime)

 

Related

» The xsi:nil attribute - http://blogs.msdn.com/b/infopath/archive/2006/11/28/the-xsi-nil-attribute.aspx

» How to: Work with the XPathNavigator and XPathNodeIterator Classes - http://msdn.microsoft.com/en-us/library/office/aa945227.aspx


InfoPath Forms Server 2010 Parameterized Submit issue


March 9, 2011 - 13:16, by Steven Van de Craen - 1 Comments

I’m currently testing our InfoPath Web Forms for an upcoming migration to InfoPath 2010 and SharePoint 2010 and have come up with a reproducible issue.

Issue

InfoPath Web Forms cannot use values from other Data Sources as parameters in a Submit Data Connection. When the form is submitted a warning “There has been an error while processing the form.” shows. From that point on the only working option is Exit Form.

image

  • It does not affect data connections to XML files, only when the query data connections connects to a Web Service
  • It does not affect the offline version of the form (InfoPath Filler 2010)
  • Tested in both December 2010 Cumulative Update and February 2011 Cumulative Update for SharePoint 2010

Set up

  1. Create a new InfoPath Web Form
  2. Add a Query Data Connection to retrieve data from a Web Service

    InfoPath Query Data Connection
  3. Add a Submit Data Connection to submit data to a Web Service. Configure at least 1 parameter (if more then one) to link to a value from the above Query Data Connection

    InfoPath Submit Data Connection
  4. Configure the form to submit using the above connection

    Submit Options
  5. Publish the form to SharePoint 2010 and open a new form in the browser

Workaround

Store the value of the query data connection in an intermediary field in the form (“Main” Data Connection). Configure the Submit Data Connection to use the intermediary field value as parameter for the Submit. You can store the value as late as possible using Rules in Submit Options or your own submit buttons.


SharePoint URL Changes and InfoPath Forms


March 8, 2011 - 10:28, by Steven Van de Craen - 0 Comments

InfoPath Form Template URL

We have a solution that makes extensive use of online and offline InfoPath forms in a MOSS 2007 environment. An upgrade to SharePoint 2010 is due in a few months, including a redesign of Managed Paths and Site Collection ‘hierarchy’ having a direct effect on the URL of our Site Collection.

I thought this meant a lot of work for converting the thousands of InfoPath XML Forms by script, because they all contained an absolute URL to the InfoPath Form Template.

However as it seems after restoring the Site Collection all forms automagically had a corrected absolute URL to their template !!

<?xml version="1.0"?>
<?mso-infoPathSolution productVersion="12.0.0" PIVersion="1.0.0.0" href="https://public.contoso.com/sites/csapp/FormServerTemplates/LeaveRequest.xsn" name="urn:schemas-microsoft-com:office:infopath:LeaveRequest:-myXSD-2009-05-29T07-59-01" solutionVersion="1.0.0.422" ?>
<?mso-application progid="InfoPath.Document" versionProgid="InfoPath.Document.2"?>
<my:Data  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xmlns:dfs="http://schemas.microsoft.com/office/infopath/2003/dataFormSolution"
          xmlns:tns="http://public.contoso.com/webservices"
          xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
          xmlns:http="http://schemas.xmlsoap.org/wsdl/http/"
          xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/"
          xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
          xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/"
          xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/"
          xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
          xmlns:xhtml="http://www.w3.org/1999/xhtml"
          xmlns:ns1="http://schemas.xmlsoap.org/soap/envelope/"
          xmlns:my="http://schemas.microsoft.com/office/infopath/2003/myXSD/2009-05-29T07:59:01"
          xmlns:xd="http://schemas.microsoft.com/office/infopath/2003"
          xml:lang="nl-be">
  <!-- Form content -->
</my:Data>
 

Default Alternate Access Mapping

What happens is that when you restore a Site Collection backup, it looks up the Web Application by the URL you specified as a parameter. From that Web Application, it takes the Alternate Mapping configured on the "Default” Zone and uses that URL to construct the absolute URL in the InfoPath XMLs.

Only at restore time

This mechanism only seems to trigger when the restore takes place. Changing the Default AAM afterwards to a different URL has no effect. You could temporarily change the AAM for the restore operation and then set it back if you want. Beats any script iterating and updating all Form XMLs any day.

 

Most of the times you expect the worst from SharePoint, but then it catches you by surprise and brings a huge smile to the face :)


Deserialize + serialize an InfoPath Form loses the processing instructions


January 21, 2010 - 17:16, by Steven Van de Craen - 0 Comments

Using xsd.exe you can generate a Class from your form schema (xsd) and then deserialize a form to an instance of that class. This makes it a lot easier to interact with its data.

CS class based on XSD

The code for serialization and deserialization might look like this:

public static T Deserialize<T>(Stream s)
{
T result = default(T);
    XmlSerializer serializer = new XmlSerializer(typeof(T));
    using (XmlTextReader reader = new XmlTextReader(s))
    {
         result = (T)serializer.Deserialize(reader);
    }
    s.Close();
    return result;
}
public static T Deserialize<T>(string s)
{
    return Deserialize<T>(new MemoryStream(Encoding.UTF8.GetBytes(s)));
}
public static string Serialize<T>(T o)
{
string result = null;
    XmlSerializer serializer = new XmlSerializer(typeof(T));
    XmlWriterSettings settings = new XmlWriterSettings(); 
    settings.Indent = true;
    settings.Encoding = Encoding.UTF8;
    using (MemoryStream stream = new MemoryStream()) 
    {
         using (XmlWriter writer = XmlTextWriter.Create(stream, settings))
         {
             serializer.Serialize(writer, o);
         }
         stream.Flush(); 
         result = Encoding.UTF8.GetString(stream.ToArray());
    }
    return result; 
}

However you lose the original processing instructions at the top of the XML file. If you want to keep those either do custom serialization using an XmlWriter or do some kind of merge code with the original XML and the XML coming from serialization.

InfoPath XML Processing Instructions

Quite obvious if you think about it but I keep forgetting it :)


SharePoint 2007: December Update


December 29, 2008 - 12:16, by Steven Van de Craen - 0 Comments

This update really combines all previous updates so installation order is simplified.

  1. WSS SP1 (+ for all language packs)
  2. MOSS SP1 (+for all language packs)
  3. WSS December Update: x86 - x64 (separate downloads !)
  4. MOSS December Update: x86 - x64 (separate downloads !)

More info about that here: Announcing December Cumulative Update for Office SharePoint Server 2007 and Windows SharePoint Services 3.0

If you're extracting the MOSS December Update for 64 bit (368073_intl_x64_zip.exe) you might run into this error:

An error occurred while unzipping. One or more files were not succesfully unzipped. The error code is 110.

A workaround is to extract the archive using WinRAR (http://www.rarlabs.com/) and it will extract the files (you still need the password from the email of course).


Infrastructure Update, August Update, October Update, Service Pack 2


October 30, 2008 - 13:43, by Steven Van de Craen - 3 Comments

update (December Update):

The December Update was released recently and is a real cumulative update which simplifies installation quite a bit. Read more about it here: SharePoint 2007- December Update

 

It's hard to keep up with the updates for SharePoint these days.

Only yesterday I upped one of our servers to August Cumulative Update (link) and the very same day a post about the October Cumulative Update (link) appears.

Can't wait for Service Pack 2 (link) to bundle all previous fixes into a single package.

update:

Figured I'd post my own rundown on this (compiled using the information from the above links) and a screen of the corresponding hotfixes. Don't worry about the 6 different languages; that's just because some of our setups have them as language pack.

Installation order

01. WSS 3.0 SP1 (x86, x64)
    > Language Pack SP1 (x86, x64) is advised for all LPs

02. MOSS 2007 SP1 (x86, x64)
    > Language Pack SP1 (x86, x64) is advised for all LPs

03. The WSS 3.0 Infrastructure Update (x86, x64)
    > not language specific (the download is identical for all languages)

04. MOSS 2007 Infrastructure Update (x86, x64)
    > not language specific (the download is identical for all languages)

05. KB953397: Excel Server Security Update (Global) (x86, x64)
    > not language specific

06. KB955586: Document Lifecycle Workflow Update (x86, x64)
    > not language specific (even though filename mentions en-US)

07. KB956057: August Cumulative Update for WSS 3.0 (Global) (x86 only)
    > not language specific

08. KB957109: August Cumulative Update for WSS 3.0 (Local) (x86, x64)
    > must be installed for each SKU or LP language

09. KB956056: August Cumulative Update for MOSS 2007 (Global) (x86 only)
    > not language specific

10. KB957691: October Cumulative Update for WSS 3.0 (Global) (x86 only)
    > not language specific

11. KB957693: October Cumulative Update for MOSS 2007 (Global) (x86 only)
    > not language specific

12. KB958567: October Cumulative Update for MOSS (Local) (x86, x64)
    > must be installed for each SKU or LP language

13. KB958569: October Cumulative Update for MOSS 2007 Workflow (Global) (x86 only)
    > not language specific

 

Q & A

Q. Is the WSS Language Pack a prerequisite for the MOSS Language Pack ?
A. No, the WSS Language Pack is required only for standalone WSS installations. Yes, as cleverly noted in the comments by Peter Depoorter the following article (link) mentioning this requirement. Thanks Peter !

Q. Do all Language Packs need to be the same level (eg. SP 1) as each other or the main product ?
A. You can mix different levels of Language Packs but needless to say it is best to have the latest version of all.

Q. Is there an Infrastructure Update or Cumulative Update for Language Packs ?
A. At current the latest Language Pack level is SP1. There are no IU, ACU or OCU updates for the Language Packs yet.

Q. Some hotfixes are only for 32bit (x86) so where can I find the 64bit variant ?
A. If there's no 64bit version listed then it only applies to 32bit setups.

Q. I'm getting "The expected version of the product was not found on your system" when running update X ?
A. We've seen this twice and it was due to Language Packs not having SP1 applied. So make sure all (both WSS and MOSS) language packs are updated to the latest version.

Hope this clears things up a bit !


Forms Server: userName() function and Forms Based Authentication


October 20, 2008 - 14:15, by Steven Van de Craen - 2 Comments

So you have an InfoPath 2007 form that renders as a Web page and you use the userName() function to get the current user. This works fine when you're using Windows Authentication but stays empty when you're using Forms Based Authentication !!

Also note that for Windows Authentication it doesn't return the domain part just username...


Forms Server: XmlFormView and setting the InitialView on load


October 10, 2008 - 12:50, by Steven Van de Craen - 13 Comments

I have been struggling with this for too long and the result is still not quite satisfying but it'll have to do for now.

I have a Web Control that renders an InfoPath form using the Microsoft.Office.InfoPath.Server.Controls.XmlFormView control and want the form to open with a specific View rather than the default one.

Browsing the web I found the following candidates:

  • xmlformView.XmlForm.ViewInfos.SwitchView(...)
  • xmlformView.XmlForm.ViewInfos.Initial = ...

Call one of these too early in the life cycle of your Control and the XmlForm instance is not yet available. Call them too late and the ViewInfos will not be changeable. I haven't really figured this one out yet...

I thought I had it when I was doing this in the Initialize event of the xmlformView instance, but no luck. Perhaps I'm doing something wrong ?

    public class MyControl : WebControl
    {
        Microsoft.Office.InfoPath.Server.Controls.XmlFormView xmlFormView;

        protected override void OnInit(EventArgs e)
        {
            xmlFormView = new XmlFormView();
            xmlFormView.Initialize += new EventHandler<InitializeEventArgs>(xmlFormView_Initialize);
        }

        protected void xmlFormView_Initialize(object sender, InitializeEventArgs e)
        {
            if (null != xmlFormView.XmlForm)
                xmlFormView.XmlForm.ViewInfos.Initial = xmlFormView.XmlForm.ViewInfos["View 2"];
        }
    }

Anyway, I kinda gave up on this and tricked my way out using javascript:

"Write some javascript that runs on page load and triggers the 'switch view' javascript method."

<script type='text/javascript'>
     var hid = document.createElement('input');
     hid.setAttribute('id', 'hidInitialView');
     hid.setAttribute('type', 'hidden');
     hid.setAttribute('value', 'View 2');
     setTimeout('Toolbar.HandleViewDropdown(hid);', 1000);
</script>

I have implemented this in a custom control inheriting the XmlFormView. Although I don't like doing it this way it's here to download: XmlFormView.cs

And I'm still hoping for a better solution... ;)

References: