Microsoft InfoPath 2010
The official blog of the Microsoft InfoPath team

Submitting to 'this' document library

Submitting to 'this' document library

Rate This

Have you ever needed to develop an InfoPath form template that submits back to a SharePoint document library but you did not initially know the server or library name when developing the form? Or have a scenario where your InfoPath form template could be published (or added as a content type) to multiple SharePoint document libraries and you need the submit location to be dynamic? Well read on to find out how you can do this!

When you create an InfoPath form template that needs to be able to submit to a SharePoint document library, you need to specify that connection in the initial design of the form template. However, at run time you can use managed code to determine the server and library name where the form was launched and then modify the “FolderUrl” property of the submit data connection so the form is submitted to the appropriate library.

So let’s get started setting up this sample. The C# walkthrough below uses the new InfoPath 2007 managed object model; below, you will find attached the same logic implemented in InfoPath 2003 managed object model and in InfoPath 2003 JScript.

Step 1: Create a sample InfoPath Form Template

Create a browser-compatible form template as following:

  1. Add 3 text box controls, all with a data type of text, named as follows: strFormURL, strLocation and strFolderName
  2. Add a “Submit” data connection named “Main submit”:
    • Set the document library name to a dummy SharePoint document library (i.e. http://server/dummyLib)
    • Use the concat function to concatenate the strFolderName field and _Test for the File Name property: concat(my:strFolderName, "_Test")
    • Enable the Allow overwrite if file exists property
  3. Set the Security Level of the form to Full Trust and sign the form template with a digital certificate
  4. Enable the Submit functionality (Tools | Submit Options) and choose the “Perform custom action using code” option

Now that we have the form, controls and submit functionality, let’s add the code to make this process work:

 

Step 2: Add the code

  • Click the Edit Code button on the Submit Options dialog
  • Create the following FormState Dictionary object – this will be used to store the form’s location when the form is initially opened:

private object _strUri
{
   get { return FormState["_strUri"];
  
set { FormState["_strUri"] = value; }
}

 

  • Add the following code to the Forms Loading event: 

// Get the Uri (or SaveLocation in a browser form) of where
// the form was opened.
// See if the form was opened in the browser

Boolean OpenedInBrowser = Application.Environment.IsBrowser; 

// If so, we will get the "SaveLocation" from the InputParameters

if (OpenedInBrowser)
  
_strUri = e.InputParameters["SaveLocation"].ToString();
else  

   //If it was opened in the client, we will get the Uri
  
_strUri = this.Template.Uri.ToString();

 

// Populate the fields on the form - keep in mind, this

// not necessary - this is simply to see the results

PopulateLibInfo(OpenedInBrowser);

 

  • Add the following procedure to the Forms class: 

private void PopulateLibInfo(Boolean OpenedInBrowser)

{

// Create a Navigator object for the main DOM
XPathNavigator xnDoc = this.MainDataSource.CreateNavigator();

 

// Create Navigator objects for each field

XPathNavigator xnFormURL = xnDoc.SelectSingleNode("my:myFields/my:strFormURL", this.NamespaceManager);
XPathNavigator xnLocation = xnDoc.SelectSingleNode("my:myFields/my:strLocation", this.NamespaceManager);

XPathNavigator xnFolderName = xnDoc.SelectSingleNode("my:myFields/my:strFolderName", this.NamespaceManager);

 

// Get the Uri stored in the FormState Dictionary variable

string strUri = _strUri.ToString();

 

// Create a variable to store the path (URL) to the document library

string strPath = "";

if (OpenedInBrowser == true) {

   //If we are open in the browser, the strUri value is just

   //the server name and library - so we just need to get

   //the URL without the last "/"

   strPath = strUri.Substring(0, strUri.LastIndexOf("/"));

} else {

   // Parse just the path to the document library -

   // this would return something like this:

   //  http://server/library

   strPath = strUri.Substring(0, strUri.IndexOf("Forms") - 1);
}


// Now, parse the URL to where the document library resides;
// this would return something like:

//    http://server or http://server/site
string strLoc = strPath.Substring(0, strPath.LastIndexOf("/"));


// Lastly, parse the URL to return just the document library name -

// in this case,we are looking for the last "/" character

// knowing that what comes after this is the document library name

string strFolder = strPath.Substring(strPath.LastIndexOf("/") + 1);

 

// Populate the fields on the form – we will use these

// values in the Submit process

xnFormURL.SetValue(strUri);

xnLocation.SetValue(strLoc);

xnFolderName.SetValue(strFolder);
}

 

  • Add the following code to the form’s Submit event:

// Create a Navigator object for the main DOM
XPathNavigator xnDoc = this.MainDataSource.CreateNavigator();


// Create Navigator objects for the fields we will

// use to modify the FolderUrl
XPathNavigator xnLocation = xnDoc.SelectSingleNode("my:myFields/my:strLocation", this.NamespaceManager);
XPathNavigator xnFolderName = xnDoc.SelectSingleNode("my:myFields/my:strFolderName", this.NamespaceManager);

 

// Get a reference to the submit data connection

FileSubmitConnection fc = (FileSubmitConnection)this.DataConnections["Main submit"]; 

 

// Modify the URL we want to submit to by concatenating the

// xnLocation and xnFolderName values

fc.FolderUrl = xnLocation.Value + "/" + xnFolderName.Value;

 

// Execute the submit connection

try

{

   fc.Execute();

   e.CancelableArgs.Cancel = false;

}

catch (Exception ex)

{

   e.CancelableArgs.Cancel = true;
}

 

  • Build and save the project
  • Publish and test

And that is it! You now have an InfoPath form template that will submit to whatever document library the form was opened from so you do not need to know this information when designing the template.

 

Scott Heim

Support Engineer

Attachment: submitToThisLibrary.zip
Leave a Comment
  • Please add 4 and 1 and type the answer here:
  • Post
  • Hi Marc,

    How are you testing? Did you deploy the form to your SharePoint site? Also - did you "install" this form on the the client machine?

    Scott

  • Hi Scott,

    Yes, I deployed to a sharepoint site and installed this form on my client machine on the development environment. In production I have a certificate so that I don't have to install the form on the client machines. I attached VS to the infopath process, put a break in the on load and filled out a new form and inspected the contents of the variable.

    Thanks for your input,

    Marc

  • Hi Marc,

    When you install a form template, then the code that I supplied as a sample is returning the correct data: it is the Uri of the installed form - not from the SharePoint doc lib. I would suspect that is most cases, if you deploy a form template to SharePoint, you will not be "installing" it to the client machines. (Hence, I did not test for this scenario.) If you needed to install the template on your dev machine just for testing purposes then you can simply create a "self-cert" and use this instead.

    In short - to test the sample code, you will need to uninstall your form.

    Let me know if this works for you!

    Scott

  • Scott,

    I installed the office 2003 certification support, created a certificate, signed my compiled infopath template with it and last but not least deployed the form to my sharepoint document library.

    1) The url problem is solved. I get the nice url that I was looking for ...

    2) When I try to submit, I can't submit because my certificate is not from a trusted authority, which makes sense to me because I generated it.

    And of course my full development environment is on one machine, a virtual one but that does not matter. It's a 2003 with Sharepoint services, visual studio, infopath, etc.

    I get the following error:

    InfoPath cannot submit the form.

    An error occurred while the form was being submitted.

    InfoPath cannot load this form. The signature on this form is not from a trusted publisher.

      at Microsoft.Office.Interop.InfoPath.SemiTrust.DAVAdapter.Submit()

      at Microsoft.Office.Interop.InfoPath.SemiTrust.DAVAdapterObjectWrapper.Submit()

      at Microsoft.Office.Interop.InfoPath.SemiTrust.DAVAdapterObjectWrapper.Submit()

      at eLNSolution.eLNSolution.DoSave() in c:\documents and settings\administrator\my documents\visual studio projects\elnsolution\formcode.cs:line 420

      at eLNSolution.eLNSolution.OnSubmitRequest(DocReturnEvent e) in c:\documents and settings\administrator\my documents\visual studio projects\elnsolution\formcode.cs:line 357

      at Microsoft.Office.Interop.InfoPath.SemiTrust._XDocumentEventSink2_SinkHelper.OnSubmitRequest(DocReturnEvent pEvent)

    Am I missing something ?

    Marc

  • Hi Marc,

    I am a bit confused I think: are you using InfoPath 2003 or 2007? (You mentioned certificate support from 2003.) Also - you set the secuity level of the form template to Full Trust - correct?

    Scott

  • Scott,

    I'm using Infopath 2003 with C# code for the form.

    The security level is full-trust (managed code). THat's the reason why I install the form on my development machine. I production, there is a certificate.

    Marc

  • Hi Marc,

    Thank you for the clarification. When you launch the InfoPath form from your SharePoint library, do you see a security prompt with options to Open , Trust this Publisher, etc.?

    I do all of my testing with a Self-Cert and this process works for; however, I do see this prompt when I launch the form. I choose Open (not Always Trust) and the submit works as well.

    If you do not see this prompt, try this for me:

    - Open your XSN in Design View

    - From the Tools menu choose Form Options

    - Select the Security tab

    - Click the Create Certificate button to create a new certificate

    - Select this new cert as the cert to sign the XSN

    - Re-publish and test

    Scott

  • Scott,

    Yes I see the form. I click the always trust and then yes.

    I tried first with the "create certificate" in Infopath. Deployed and tested. WORKS

    I tried again with the other certificate. Deployed and tested. It WORKS also.

    Gues I've done something wrong last week ...

    Thanks for your support,

    Marc

  • Thanks for letting me know Marc - I am certainly glad you were able to get this working!

    Scott

  • Hi Scott,

    Thank you for posting this - I have been looking for such a solution for a LONG time.

    This solves one of my two problems.

    The second problem is related:

    Is it possible to have a receive location that is dynamic? I have an InfoPath 2007 form which receives data from a SharePoint list (to populate a drop down) and would like the server name part of the url to be dynamic.

    I have tried doing this using the following code:

    SharepointListQueryConnection mylist = (SharepointListQueryConnection)this.DataConnections["mylist"];

    mylist.SiteUrl = new Uri("http://otherserver/TheList");

    but the SiteUrl property is read-only.

    Is there any way to do this?

  • Hi,

    Sorry for the delay in getting back to you on this. Unfortunately, I don't see a way to accomplish this as there are no methods to update these values.

    Scott

  • Hi,

     I am using InfoPath 2003 and SharePoint v2. I was able to use the solution above on a test form and work perfectly.

    Now when I try to add this code to the forms I have in production Iam getting a compiling error " 'null' is null or not an object File: script.js Line:92"

    Line 92 is "xnFormURL.text = strUri;

    These forms are also conected to a SQL DB backend, not sure if that could be causing the problem. Any assistance in getting this to work would be greatly appreciated. Thanks!

  • Hi,

    It sounds like your xnFormURL object is null - which is typically caused by an invalid XPath expression to that node.

    You will need to step through your code and make sure the XPath expression is correct.

    Scott

  • First of all I would like to say THANK YOU to everyone who came to my sessions last week! I had a wonderful

  • One scenario that I have had trouble with is if you publish the form as a content type on the site collection. In that situation, the form is published under the site collection url, not the form library url.

    I set a document library under that site collection to manage content types and I select the content type to be the one that was published using infopath. When I click new on the document library and select that content type, it opens the form in the infopath client. However, I'm unable to capture the form library url that I was in.  

    How can I capture that url so that I can use it to change the path of the submit dynamically?

Page 2 of 12 (166 items) 12345»