Submitting to ‘this’ document library


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

submitToThisLibrary.zip

Comments (166)

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

  2. fordhamSteve says:

    I think you are missing this line of code from your Submit event:

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

  3. Scott Heim says:

    Hi fordhamSteve,

    Thank you for alerting us to the missing line of code – the sample has now been corrected.

    Scott Heim

  4. dlgross says:

    I am getting the following error when i try to preview my form. I have limited experience with javascript.

    Any idea what I might have done wrong? Thanks, Dean

    InfoPath cannot open the selected form because of an error in the form’s code.

    The following error occurred:

    Expected ‘;’

    File:script.js

    Line:8

    private object _strUri

  5. Scott Heim says:

    Hi Dean,

    Most likely the cause of this problem is the fact that this code is C#.NET and not JScript. If you want to test using the same form and C#, you will need to remove the JScript code first and then set the form to use C#:

        – Open the XSN in Design View

        – From the Tools menu choose Form Options

        – Select the Programming Category

        – Click the Remove Code button to remove the JScript files

        – From the Form Template Code Language box choose C#

    Scott

  6. dlgross says:

    Scott, thanks, When I look at the Form Options, Advanced tab, there is no Programming Category, there is only a Programming Language box with Form Code Language choices of JScript and VB Script. I’m using IP 2003 SP1. How do I make it use C#?

    Dean

  7. Scott Heim says:

    Ah – 2003…that’s a bit different. Do you need to use this form or can you start over with a new form? Either way, you will need to use the Visual Studio Tools for Office InfoPath Toolkit (in conjunction with Visual Studio) to create a managed code solution. If you don’t have Visual Studio then the only code options available are JScript and VBScript and you will need to convert the C# code to JScript.

    Scott

  8. dlgross says:

    I was just testing your approach to see how it would work in a dummy form before I tried to implement it in an existing form. I do have VS 2003 with the toolkit. Would it be worthwhile to get VS 2005 if this is the only coding that I’m doing?

    Dean

  9. Scott Heim says:

    Hi Dean,

    Certainly there are some benefits to moving to VS2005 but although I have not tried it, theoretically the same basic process/code should work using the managed code option with VS2003.

    Scott

  10. dlgross says:

    Scott, is this supposed to work with IP 2003 or 2007? I keep getting compile errors in 2003.

    Dean

  11. Scott Heim says:

    Hey Dean,

    Although that code is C#, it is specific to the new object model in 2007. To get this to work in 2003, you will need to convert that code to the 2003 object model.

    Scott

  12. infopath says:

    By popular demand, Scott converted the code used in this article into the InfoPath 2003 managed object model (in C#) and into JScript. You can download the full listing in the attachments section above.

    Alex

  13. dlgross says:

    Thanks for making the conversions Scott, I’m getting closer to getting this to work, but I don’t have a Digital Certificate. Is there any workaround available? Dean

  14. Scott Heim says:

    Hi Dean,

    Glad you hear you are making headway! For testing purposes, you can create a "self-cert" (basically a certificate that does not have a chain of trust, hence it is only valid on the machine in which it was created) by choosing the Create Certificate button in Tools | Form Options | Security and Trust category.

    Scott

  15. nemegeerm says:

    Hi,

    When I add the code strUri = thisXDocument.Solution.URI; to get the url I get a uniform resource identifier (urn:eLNDTX:Innx). Am I missing something ? Why don’t I get a url ??

    Marc

  16. infopath says:

    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

  17. nemegeerm says:

    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

  18. infopath says:

    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

  19. nemegeerm says:

    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 settingsadministratormy documentsvisual studio projectselnsolutionformcode.cs:line 420

      at eLNSolution.eLNSolution.OnSubmitRequest(DocReturnEvent e) in c:documents and settingsadministratormy documentsvisual studio projectselnsolutionformcode.cs:line 357

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

    Am I missing something ?

    Marc

  20. infopath says:

    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

  21. nemegeerm says:

    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

  22. infopath says:

    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

  23. nemegeerm says:

    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

  24. infopath says:

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

    Scott

  25. ivl says:

    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?

  26. infopath says:

    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

  27. derrickgh@hotmail.com says:

    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!

  28. infopath says:

    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

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

  30. shirinp says:

    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?

  31. Scott Heim says:

    Hi shirinp,

    Unfortunately I have not found a way around this…other than displaying the form in the browser instead of the client. This should allow you to capture the form library URL. If you must open it in the client and have it published as a site content type, I know of no way to capture this information.

    Scott

  32. zullu says:

    Hi Scott,

    I have tried the attached solution for Infopath 2007 C# code.

    I am getting an error: "System.ArgumentOutOfRangeException, Length cannot be less than zero."

    – in the PopulateLibInfo function at the line where you are trying to Parse the path to doc library to return something like: http://server/library.

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

    When I look at the value returning from strUri.IndexOf("Forms"), I can see it is returning "-1".

    Am I going wrong somewhere!

    Thanks in advance for any kind of help.

    zullu.

  33. infopath says:

    Hi zullu,

    Where did you publish the form and how are you trying to open it?

    Scott

  34. BobC says:

    shirinp,

    Just so you know, you are not alone regarding this problem…

    I also tried passing a parameter indicating the location, but wss doesn’t allow parms to be set for a content type.  Unless Scott has an idea for this.

  35. BobC says:

    I get prompted for the file name.  How do I set this in code?

  36. infopath says:

    Hi BobC,

    You would typically use a field in the data source to store the name of the submitted form. So you can either set this using a Rule or use code similar to the following:

    XPathNavigator xnDoc = this.MainDataSource.CreateNavigator();

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

    xnFormName.SetValue("Form1");

    Scott

  37. pkarpati says:

    I’ve tried to call this.Submit() method with your sample code in my own Button Clicked event, but the Forms Server tell me that I cannot call XmlForm.Submit in a SubmitEventHandler.

    I want to do this because I need to call Rules before Submit in your way.

    Can you help me?

    Peter

  38. infopath says:

    Hi pkarpati,

    You have a couple of options:

    – Change your button to simply be a "Submit" button (don’t use code)

    – Use the click event of the button to call the same code that is in the "Submit" event and remove the Submit event handler.

    NOTE: if you use the 2nd option, you will  need to remove the "e.CancelableArgs" lines.

    Scott

  39. RChakravarti says:

    Hello Scott,

    I have a question, regarding using CODE to save the form instance to a subfolder that only an admin can see.

    USE CASE:

    ========

      Once a user enters a form (such as a survey in WSS3, through a web enabled InfoPath form), the user should not be able to re-open OR read any other entries by other people.

    We thought we could have a folder called "Submitted" in the WSS library, where the form could be saved using the "SaveLocation" QueryString property, and that this folder could only be permissioned to be viewable by "Admins".

    ISSUE:

    =====

    Even when we used SPSecurity.RunWithElevatedPrivileges(),  we get an access denied for anyone NOT AUTHORIZED to see the "Submitted" subfolder. We are unable to fgiure out why.. When logged on as admin, the save works just fine.

    —————

    public void FormEvents_Submit(object sender, SubmitEventArgs e)

           {

               SPSecurity.RunWithElevatedPrivileges(delegate()

               {

                   // 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 = "http://servername:3000/sites/testsite/Feedback/Submitted";

                   // Execute the submit connection

                   try

                   {

                       fc.Execute();

                       e.CancelableArgs.Cancel = false;

                   }

                   catch (Exception ex)

                   {

                       e.CancelableArgs.Cancel = true;

                   }

               });

           }

    —————

    NOTE:

    a) The form library is called "Feedback" with a subfolder "Submitted" which has Admin Rights only.

    b) Users instantiate a form instance through a custom link which has the SaveLocation QueryString param pointing to the (hidden) "Submitted" folder, with the desired behaviour of them not being able to see the form once submitted.

    Any help you can provide would be great.

    Thanks,

    Rajiv

  40. infopath says:

    Hi Rajiv,

    There is no built-in InfoPath functionality to limit the forms a user can see once submitted. You could create a custom SharePoint "View" that uses the "[Me]" filter to limit what documents they see when they open that library; however, this is not "security" per sé just a filter.

    Regarding the permissions not working – I believe you would be better served by asking this of the SharePoint group.

    Scott

  41. kalanineelesh@rediffmail.com says:

    I am also facing the same problem as Shirinp. In my case, i upload the form to the form server and then activate it to a particular sitecollection.

    of cNow i have a number child sites in tht sitecollection which will use this form content type, so i need to find a way to get the URL of the form library at run time. Ofcourse this post solves the problem for the forms that are opened using the browser but what to do in case forms are opened using Infopath?

    Have anybody got the solution for the problem ?

  42. kalanineelesh@rediffmail.com says:

    Also, I am able to submit the new form using this method, but how can i resubmit or save the same form when it is opened in edit mode.

  43. infopath says:

    Hi Neelesh,

    If I understand correctly you are asking how to open an existing form from a library, modify it and then re-save it using the same name – correct? If so, then when you setup the "submit" data connection make sure you enable the option: Allow overwrite if file exists."

    Scott

  44. kalanineelesh@rediffmail.com says:

    Hi Scott,

    Thanks for replying.

    Is there any wrok around for my first problem?

    Also, i need to add data (at run time) to a repeating table which has two columns, one consisting of checkbox and the other has text box.

    Can you pass on some links…..

    Also, is it okay to use Sharepoint object model directly in infopath code ?

    Neelesh

  45. infopath says:

    Hi Neelesh,

    As I have mentioned a couple of times before, there is no way that I know of to get this information.

    Regarding adding data at runtime, since this is a repeating node you will want to use code to accomplish this. There are a number of ways this can be done: append the new row as I am dong below or if you want to extract the form files you can get the actual "OuterXml" of the node you want to append and use this to append the row or if this is a client-only form you can use the "ExecuteAction" method to add a new row.

    The following sample assumes the following:

    – A secondary data connection to the SQL Server Northwind Shippers table – this connection is called Shippers

    – A Repeating Table with 3 columns: f1_ID, f2_CompanyName and f3_Phone

    – On the Loading event of the form, I populate those repeating table fields using the following code:

    public void FormEvents_Loading(object sender, LoadingEventArgs e)

           {

               //Create a NamespaceManager to use when referencing namespaces

               XmlNamespaceManager ns = this.NamespaceManager;

               //Create an XPathNavigator object for the main DOM

               XPathNavigator xnDoc = this.MainDataSource.CreateNavigator();

               //Create an XPathNavigator object for the Repeating Table node

               XPathNavigator xnRepeatingTable = xnDoc.SelectSingleNode("/my:myFields/my:group1", ns);

               //Create a DataSource object for our secondary data connection

               DataSource dsShippers = this.DataSources["Shippers"];

               //Create an XPathNavigator object for the data source

               XPathNavigator xnShippers = dsShippers.CreateNavigator();

               //Create an XPathNodeIterator object so we can enumerate all the records from the

               //secondary data connection

               XPathNodeIterator xiShippers = xnShippers.Select("/dfs:myFields/dfs:dataFields/d:Shippers", ns);

               //Loop through those records

               while (xiShippers.MoveNext())

               {

                   //Create string variables for all the fields we need to populate

                   //in the Repeating table

                   string strID = xiShippers.Current.SelectSingleNode("@ShipperID", ns).Value;

                   string strCompanyName = xiShippers.Current.SelectSingleNode("@CompanyName", ns).Value;

                   string strPhone = xiShippers.Current.SelectSingleNode("@Phone", ns).Value;

                   //Use the AppendChild method to add a new row to the repeating table and

                   //concatenate each field value appropriately

                   xnRepeatingTable.AppendChild("<my:group2><my:f1_ID>" + strID + "</my:f1_ID><my:f2_CompanyName>" + strCompanyName + "</my:f2_CompanyName><my:f3_Phone>" + strPhone + "</my:f3_Phone></my:group2>");

               }

               //Cleanup

               ns = null;

               xnDoc = null;

               xnRepeatingTable = null;

               dsShippers = null;

               xnShippers = null;

               xiShippers = null;

           }

    I hope this helps!

    Scott

  46. kalanineelesh@rediffmail.com says:

    Many Thanks for the suggestions.

    That worked perfectly.

    If some one also wish to clear the repeating tables befor filling them…following code will be useful:

    string NodeGroup = /my:myFields/my:group7/my:openTable";

    XPathNavigator FirstNode = MainDataSource.CreateNavigator().SelectSingleNode(NodeGroup + "[1]", NamespaceManager);

                   XPathNavigator LastNode = MainDataSource.CreateNavigator().SelectSingleNode(NodeGroup + "[position()=last()]", NamespaceManager);

                   if(FirstNode != null)

                   {                  

                       if (LastNode != null)

                       {                    

                           FirstNode.DeleteRange(LastNode);

                       }

                       else

                       {

                           FirstNode.DeleteSelf();

                       }

                   }

  47. kalanineelesh@rediffmail.com says:

    I have one more query.

    One of the field in the repeating table is a date field and i am populating it from sharepoint list. it shows me the validating screentip "Only Date allowed".

    I have not applied any validation and also the date which i am filling in the date filed is in the same format as specified for that field.

    I also tried to delete the nil attribute but still no luck.

    Any clues…

  48. infopath says:

    Hi neelesh,

    Here is some sample code that works for me – in this case, "field1" has a "Date" data type:

    XmlNamespaceManager ns = this.NamespaceManager;

               XPathNavigator xnDoc = this.MainDataSource.CreateNavigator();

               XPathNavigator xnDateField = xnDoc.SelectSingleNode("/my:myFields/my:field1", ns);

               //Remove the "nil" attribute

               if (xnDateField.MoveToAttribute("nil", "http://www.w3.org/2001/XMLSchema-instance&quot;))

                   xnDateField.DeleteSelf();

               xnDateField.SetValue("2007-10-12");

               ns = null;

               xnDoc = null;

               xnDateField = null;

    Scott

  49. kalanineelesh@rediffmail.com says:

    Hi Scott,

    I have already tried the same code, but it does not works.

    In my case, i am first adding the row to the repeating table at run time using the code:

    xnRepeatingTable.AppendChild("<my:group2><my:MyDate></my:MyDate></my:group2>");

    Where, MyDate is the date field which is initialy empty and also not having any nil attribute.

    After this i wrote the code to remove the nil attribute and set the value of the date field which is as follows:

    XPathNavigator xnDoc = this.MainDataSource.CreateNavigator();

              XPathNavigator xnDateField = xnDoc.SelectSingleNode"/my:myFields/my:group1/my:group2" + "[" + Index of the row+ "]" + "/my:MyDate", ns);

              //Remove the "nil" attribute

              if (xnDateField.MoveToAttribute("nil", "http://www.w3.org/2001/XMLSchema-instance&quot;))

                  xnDateField.DeleteSelf();

              xnDateField.SetValue("2007-10-12");

    But it still showing me the same error.

  50. infopath says:

    Hi neelesh,

    And just to confirm, your date field is a node in your "main" DOM – correct? And if you look at the properties for this node, the data type is set to "Date (date)" – correct?

    Scott

  51. kalanineelesh@rediffmail.com says:

    Yes, That is correct.

    And i am getting the error when the date field is empty.

    I am trying to insert a blank string in a field after delting the nil vallue.

    I don’t know how to insert blank date in the field.

    Neelesh

  52. infopath says:

    Hi Neelesh,

    I am confused: in your prior response, you advised you tried the code I supplied, which actually inserts a date, failed for you. Is this correct? If you actually specify a date in the code it fails? Or does it only fail if you try to insert a blank date? (If only when inserting a blank date, why do you want to insert a blank date??)

    Scott

  53. kalanineelesh@rediffmail.com says:

    Hi Scott,

    If i use the following code to add the date field then it shows the error "can not blank", while i have not used any validations.

    xnRepeatingTable.AppendChild("<my:group2><my:MyDate></my:MyDate></my:group2>");

    Neelesh

  54. infopath says:

    Hi Neelesh,

    Can you please complete these steps and let me know the results:

    – Create a new, blank form template

    – Add a Repeating Table with just 2 columns

    – Change the name of the text box in column 1 to: textField

    – Change the name of the text box in column 2 to: dateField

    – Your data source should look like this:

    myFields

        group1

             group2

                  textField

                  dateField

    – Change the data type of dateField to: Date (date)

    – Add a button to the View

    – Add the following code to the click event of the button:

    XmlNamespaceManager ns = this.NamespaceManager;

               XPathNavigator xnDoc = this.MainDataSource.CreateNavigator();

               XPathNavigator xnTable = xnDoc.SelectSingleNode("/my:myFields/my:group1", ns);

               xnTable.AppendChild("<my:group2><my:textField>Test</my:textField><my:dateField></my:dateField></my:group2>");

    – Test – when I execute this code, the new row is added and by default, the dateField field will be required.

    Does this work for you?

    Scott

  55. kalanineelesh@rediffmail.com says:

    This is what the problem is…I do not want the date field to be made required BY DEFAULT.

  56. infopath says:

    Hi neelesh,

    Sorry about that – I guess that was the part I was not understanding. Modify the "AppendChild" line as follows:

    xnTable.AppendChild("<my:group2><my:textField>Test</my:textField><my:dateField xsi:nil=’true’></my:dateField></my:group2>");

    As you can see, I have added the attribute "xsi:nil=’true’" to that line of code. This allows for a blank value and insures the field is not required.

    Scott

  57. Brian111 says:

    Hi

    This worked great thanks.

    Is it possible to use this technique on data connections ?

    Thanks

    Brian

  58. scorphg says:

    Is there a solution like this for vb?  Here is my issue.  I have a shrepoint library which is/will be storing many documents.

    I wrote a infopath form that needs to submit the new document(s) to the sharepoint site.  I cannot use the default submit because of the need to organize the documents into specific locations/folders.  Once the form is completed, i have a field which has the "save as" filled in as well as the location with the appropriate url and folder.  so the question is how to submit to sharepoint server for this scenario.  The other scenario is "old" documents.  Those which have already been saved… how do I get the actual filename for the document, then proceed to overwrite it if any changes are made?  Is there a method which I can extract the url, filename, location/folder??

    thanks in advance

  59. infopath says:

    Hi Brian,

    Not sure I follow – are you asking if you can append data to secondary data connections in this manner?

    Hi scorphg,

    For the submit part of your question, that is what this post basically does: allow you to specify the submit location at runtime. Am I misunderstanding what you are asking?

    Scott

  60. scorphg says:

    Hi Scott,

    Thanks for the very quick response.  I dont think you are misunderstanding the question, as much as I may not be stating it correctly.  

    Basically, the question is how do i get the filename of an existing form saved to sharepoint using vb managed code?

    The c# code above is great, and I will use that for future projects, so thanks… is there the same code for vb managed code?

  61. infopath says:

    Hi scorphg,

    Sorry for the delay – it has been quite busy. You would need to parse the Uri I believe but unfortunately I don’t have any sample code for any of this in VB.

    If I get some time, I’ll see what I can come up with.

    Scott

  62. kalanineelesh@rediffmail.com says:

    How can we populate a drop down using c# code?

    I need to set both the value and the display names and also need to read those vales and display name back.

    Right now i am only able to fill the values.

    Any suggesstions?

  63. infopath says:

    Hi neelesh,

    As you have probably seen, you do not have programmatic access to controls in InfoPath. What you would need to do is either populate a repeating structure in the main DOM that the dropdown is bound to or populate an XML resource file that is used as the source of data for the dropdown or use a web service to retrieve the data.

    Scott

  64. boverton says:

    Hello,

    This code works great for the initial submit.  But when editing an existing document I get errors.  5537   Any suggestions?  I think the URLs are different for a new document submit and an edit

    cheers,

    Brad

  65. moss_sharepoint@yahoo.com says:

    Though this query does not belong to this blog, still I am posting it here as this is a very critical requirement in one of our projects.

    Is there some way to convert the browser enabled infopath 2007 file saved in the form library to pdf/word document programmatically?

    We have a windows service which will send these converted pdf/word files as an attachment in the email.

    Thanks in advance.

  66. infopath says:

    Hi Brad,

    I was finally able to get to the issue of opening and submitting an existing form and I did need to modify the code. This updated sample code is a bit verbose but I wanted to show the various steps. Here are the updates:

    – Replace the sample Loading event code with the following:

    // See if the form was opened in the browser

               Boolean OpenedInBrowser = Application.Environment.IsBrowser;

               //Variables to store the results of testing if the form

               //being opened is new and if not, the "source" location

               //parameter so we can get the server or server/site name

               Boolean newForm = true;

               string strSource = string.Empty;

               // Get the Uri (or SaveLocation/XmlLocation in a browser form) of where

               // the form was opened.

               if (OpenedInBrowser)

                   if (this.New) //We will get the SaveLocation parameter

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

                   else //We will get the XmlLocation parameter

                   {

                       _strUri = e.InputParameters["XmlLocation"].ToString();

                       newForm = false;

                       //Store the "Source" parameter so we can parse this for

                       //the server/site URL

                       strSource = e.InputParameters["Source"].ToString();

                   }

               else //Opened in the client

               {

                   //See if we are opening a new form – if so, we will get the

                   //Uri to the template

                   if (this.New)

                   {

                       _strUri = this.Template.Uri.ToString();

                   }

                   else

                   {

                       //If opening an existing form, we will get the Uri

                       //of the form we are opening.

                       _strUri = this.Uri;

                       newForm = false;

                   }

               }

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

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

               PopulateLibInfo(OpenedInBrowser, newForm, strSource);

    – Replace the sample PopulateLibInfo procedure with this one:

    private void PopulateLibInfo(Boolean OpenedInBrowser, Boolean newForm, string strSourceParam)

           {

               // 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 (newForm)

                   {

                       //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

                   {

                       //We need to get the server URL (up to the library name) so

                       //we can successfully submit the form.

                       string strServer = string.Empty;

                       //The following is broken into 2 parts so it is easier to see

                       //what we need to do:

                       //Get the URL up to the word "Forms" in the URL

                       strServer = strSourceParam.Substring(0, strSourceParam.IndexOf("Forms"));

                       //Get the URL up to the last "/" before "Forms" – this will be

                       //the server or server/site

                       strServer = strServer.Substring(0, strServer.LastIndexOf("/"));

                       strPath = strServer + strPath;

                   }

               }

               else //Opened in the client

               {

                   // Parse just the path to the document library –

                   // this would return something like this:

                   //  http://server/library

                   //NOTE: This process will not work when an ADMIN deployed form

                   //is opened in the client.

                   try

                   {

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

                   }

                   catch { }

               }

               // 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);

           }

    With these changes, you should be able to open and submit either a new or existing form.

    Scott

  67. derrickgh@hotmail.com says:

    I was able to get this work when creating a blank template but could not get it to work using a form that is connected to a SQL DB. The error I get when opening the form from SharePoint is:

    "System.NullReferenceException

    Object reference not set to an instance of an object.

      at Template13.FormCode.PopulateLibInfo()

      at Template13.FormCode.FormEvents_OnLoad(DocReturnEvent e)

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

    Will this solution work with a form that is created for a SQL DB? Thanks!

  68. infopath says:

    Hi derrickgh,

    Yes – this will work when your form template has been created from a database; however, the XPATH will be different for the fields you create in this sample. For instance, the strLocation node in this sample has an XPATH of: my:myFields/my:strLocation. However, when your form is created from a database connection, the XPATH is now: /dfs:myFields/my:group1/my:strLocation.

    It sounds as if you may not have the correct XPATH referenced. If you are using InfoPath 2007, simply right-click on each node that you have referenced in your code and choose Copy XPath. Then paste this into your code and compare.

    Scott

  69. derrickgh@hotmail.com says:

    Thanks Scott that worked!!

    One last question. The forms I need to use this on use a search functionality, so once the form is the person finds their project in a drop-down hits search and this populates the form, which in turn clears the 3 fields used for this solution. Is there a way to run the code after the search event? Thanks again for your help

  70. infopath says:

    Hi derrickgh,

    The fields that store the folder name, location, etc. – are these in your database table as well?

    Scott

  71. derrickgh@hotmail.com says:

    Scott,

    Yes, the 3 fields are in DB table.

  72. infopath says:

    Hi derrickgh,

    OK – then you can either move the code to populate these to the submit code or (the easier option) remove those fields from the database and simply add them to your datasource. Unless I am missing something from your design needs, these fields are not required to be in the database. You can display the Data Source Task Pane, right-click on the "myFields" node and choose Add. Then simply add these 3 fields. Now these will not get submitted to the database table but that should not be needed.

    Scott

  73. derrickgh@hotmail.com says:

    I moved the code under the submit button and it works perfectly. Thanks again for your help!

  74. dkarantonis says:

    Hi Scott,

    nice article.

    I have an InfoPath form created in order to be used as a workflow association form.

    I would like to retrieve the list that the workflow is (about to be) associated from the InfoPath form’s FormLoad event code.

    When the association form is loaded from the web browser (through InfoPath form services), the url is "http://vmserver/development/Company1/_layouts/CstWrkflIP.aspx?List={345EB1D6-434E-4CA9-9138-823CB320AD6C}".

    How can i get this List ID?

    When using the e.InputParameters["SaveLocation"], i get the following exception "The given key was not present in the dictionary."

    How can i get the URL?

    regards

  75. infopath says:

    Hi dkarantonis,

    In this scenario, the "List" parameter is not an "InputParameter" to the form. If you debug this you will see the InputParameter count is zero. I have been unable to find a way to get this from behind the InfoPath form – so you may want to look at trying to get the URL and parsing it from the ASPX page.

    Scott

  76. dkarantonis says:

    Hi Scott

    i finally got through it by adding a System.Web reference to my project and retreiving the list GUID from the url by using the HttpContext.Current.Request.QueryString["List"].ToString() command.

    I don’t know if this is the best way to handle this issue, but it did work for me. If there is a better way, please let me know.

    thanks for the support

  77. dkarantonis says:

    Hi Scott,

    do you have any idea about how i could programmatically retreive the workflow association name from inside the form’s code at runtime (the workflow association name is not known at design time? Is it something i could get also from the aspx page?

  78. infopath says:

    Hi dkarantonis,

    Unfortunately I do not – your best bet would probably be to post that query to a workflow forum or you could open a support case with the SharePoint folks.

    Scott

  79. boverton says:

    Hello Scott,

    quick question.  In reference to your answer

    # re: Submitting to ‘this’ document library

    Thursday, July 19, 2007 6:00 PM by infopath

    In reference to putting this code behind a button.   I need to be able to run Rules first and then submit.   This works fine but I can’t get my document to Close when submitted.   I have close document in the submit options but I don’t think they are being called because you’re going directly thru the Data connection.   Is there a way to close the form after your submit code?

  80. infopath says:

    Hi boverton,

    The easiest way is to simply add a Rule to the same button where you are executing code and the Rule will have just one action: Close the form.

    The code should execute to submit the form and then close.

    Scott

  81. mehtavipulk says:

    Hi,

    I have a InfoPath form with VSTA code embedded to it. In InfoPath development mode, we attach the project file to the .xsn form. So while  publishing the form the .xsn form compiles the project file (in to a .dll file). But how do we manage this situation in the production enviornment? If we try to publish the form (using File -> Publish option of the InfoPath form), using VSTA it will start searching for the project file & try to compile it. But in the production enviornment there wont be Visual Studio installed to map the project file & compile it while publishing the form.

    In the production enviornment how do we manage to publish InfoPath form with with embedded VSTA code?

    Regards,

    Vipul Mehta

  82. infopath says:

    Hi Vipul,

    As you know, when you compile the VSTA code behind your InfoPath form template (XSN file), the compiled DLL becomes part of the XSN. You are correct that each time you publish we attempt to compile the code; however, when you publish on a machine that does not have the project files you can simply click "Ignore" and the publish process will continue. (Obviously the other option, since you have InfoPath on that machine is to simply copy the project files to that computer and then when you get that message click the ‘Browse’ button to locate the project file.)

    Scott

  83. svarukala says:

    Scott,

    Firstly, thanks for a very useful post. We are implementing around 100 forms in SharePoint and you sample code helps a lot to make the form submission independent of the form library.

    However, I am having a problem with updating the existing form. I got your latest code you wrote in your comments which will updated an already existing form. I got it working but it has one glitch. The program is raising ‘unauthorized exception’ unless I use an account with full rights(owner). The user who created the form, is als not able to update it. I worked around it by calling the data connection submit call within SPSecurity.RunWithElevatedPrivileges block. But here is the problem, the sharepoint library columns ‘Created By’ and ‘Modified By’ are populated with ‘System Account’ or the admin account name instead of the current user name.

    So, is there any other work around for this? or Are we missing anything? Is there any explanation for this behaviour(user not able to update)? Thanks for your help.

    -Srinivas

  84. infopath says:

    Hi Srinivas,

    I had not heard this before so I just tried this on my test site and it seems to work correctly. My "TestUser" has Contribute permissions to my site – I then logged on as that user, created and submitted a new form and then successfully opened that same form, modified data and re-submitted. In this test, the form shows Modified By: TestUser.

    What you may want to look at is doing a Netmon or Fiddler trace to see if you can track down down the cause of the failure – obviously remove your workaround code. :)

    Offhand I cannot think of a reason why…do you have your form set to Full Trust?

    Scott

  85. irgendwo says:

    Hi Scott,

    My problem is that by clicking the button in infopath form published on sharepoint site i should open existing form that resides in infopath forms library and one of it’s fields should match certain value.How could i do that?Neither i found the opportunity to get the full url of existing form nor the opportunity to request the form with desired field value.

    Will be grateful for any help.

    Best regards,

    Vitaly.

  86. infopath says:

    Hi Vitaly,

    I am not sure I completely follow the issue but it sounds like you want to open an InfoPath form based on either command-line or query (URL) parameters…is this correct? If so – have you seen these:

    How to: Use Query Parameters to Invoke Browser-Enabled InfoPath Forms

    http://msdn2.microsoft.com/en-us/library/ms772417.aspx

    Command-line switches for InfoPath

    http://office.microsoft.com/en-us/infopath/HP101483281033.aspx

    Scott

  87. svarukala says:

    Scott,

    Thanks for your reply. I just tried copying your code as it is and it worked just fine. Even a user with just the contribute access is able to add and update a form. I will retest the same in my other problematic environment at my work place. I will let you know the result.

    In between, I wonder if a form can be published once and deployed into multipe environments (development, staging, production)? As of now its not possible because we have to give the URL to the sharepoint site to which we publish and so it is hardwired to the form. Technically, I agree that might not be possible because we digitally sign the form for a particular environment. But with a wild card certificate this should not be a problem right?

    Thx,

    Srinivas

  88. irgendwo says:

    Hi Scott

    Thanks for reply.

    After looking through these articles I still haven’t found the way to open the form with desired value in certain field.It should be made via some CAML query or what?

    Thanks in advance

    Vitaly

  89. infopath says:

    Srinivas – I am glad to hear the sample works as needed! In regard to publishing once – the answer could be "maybe." <G> Let me explain: If your various sites (dev, prod, etc.) are in the same farm then you could "Admin" deploy the form and then activate it to the appropriate site collections. If your various sits are not under the same farm, you could still perform the "Admin" publish and then simply move that published form where needed and then complete the Admin process of uploading and activating to the appropriate site collection.

    Keep in mind, either of these would still require the solution in this post but the process is indeed possible. The other thing you would need to consider though are data connections. Now again, you may be able to cover this with code but you do need to keep it in mind.

    Vitaly – Unless I am missing something, what you would need to do is open the 2nd form using a command-line or query parameter and then you would have code in the "Loading" event that looked for that parameter and populated the appropriate field (node) in the form.

    Scott

  90. infopath says:

    Vitaly – here is one more item on command-line/query parameters that may help:

    http://blogs.msdn.com/infopath/archive/2007/02/26/passing-data-into-a-form-input-parameters.aspx

    Scott

  91. irgendwo says:

    Hi Scott

    The thing is that the 2nd form is not always the same.It’s different every time and depends on the data in 1st form.So i think that this problem could be solved using SPQuery class from SharePoint OM.By doing so we can select what existing form to open by making the query.Could we somehow use this class in InfoPath?We should add some using directive or assembly reference?

    Thanks for your help

    Vitaly

  92. infopath says:

    Hi Vitaly,

    Yes – you can use this in your InfoPath manged code…note that you will need to develop this on your server machine.

    You will need to add a Reference to Windows SharePoint Services and then a "using" directive: using Microsoft.SharePoint;

    Once you have these in place in your managed code, you can then use the SharePoint OM.

    Scott

  93. svarukala says:

    Scott, I got it working today. I still don’t know what was the mistake I was doing. But the good the thing is its working now.

    Regarding the publishing once, I thought a form has to be published separately for each target site. I will give a try if I can deploy a form which was published to a Dev site into QA site. We have different server farm for different environments. For the data connections I am using UDC’s, so, that is taken care of. All the forms are fully trusted, admin published forms.

    Srinivas

  94. irgendwo says:

    Hi Scott

    Thanks for your help but i’ve got another question..i’ve decided to make my template browser-enabled but thus some methods of Application class,such as NewFromFormTemplate disappeared..maybe i’m missing some references or what?i’ve added references to

    C:Program FilesMicrosoft OfficeOffice12InfoPathOMMicrosoft.Office.Infopath.dll

    C:Program FilesMicrosoft OfficeOffice12Microsoft.Office.InfoPath.FormControl.dll and others but still NewFromFormTemplate method and some others are not available.What should i do in order to be capable to use them?

    Thanks in advance,

    Vitaly

  95. infopath says:

    Hi Vitaly,

    As you have seen, everything that is available for designing for the InfoPath client is *not* always available for designing for the browser. This applies not only to object model differences but also controls, etc.

    The method you are asking about is an InfoPath client-only method:

    http://msdn.microsoft.com/en-us/library/aa942326.aspx

    Scott

  96. infopath says:

    Hi Vitaly,

    As you have seen, everything that is available for designing for the InfoPath client is *not* always available for designing for the browser. This applies not only to object model differences but also controls, etc.

    The method you are asking about is an InfoPath client-only method:

    http://msdn.microsoft.com/en-us/library/aa942326.aspx

    Scott

  97. irgendwo says:

    Hi Scott

    Is there any other way to open template from form?For example knowing the URL displayed when you manually create new form from template located in forms library?

    Vitaly

  98. infopath says:

    Hi Vitaly,

    If you need to create a new form from the same template, you can set the "Submit" option: Create a new, blank form – this way when your form is submitted, a new blank form will be created. And if you currently do not have a submit connection, you could create one just to "Submit to host" – won’t really do anything other than cause a server postback and then create a new form. (It will obviously create a new form so all existing data is gone.)

    However, I don’t believe it is possible to create a new form from a different template. In fact – as you have seen, programmatically creating a new template from the same one is not supported – nor is the Rule to create a new form (this too is not available for forms services.)

    So short of the above submit option, I don’t believe there is a way to do this. (Other than maybe using your own ASPX page to host the XmlFormView control and using code behind your ASPX page to launch a new form.)

    Scott

  99. irgendwo says:

    Hi Scott

    It’s a pity there’s no simple way to do this..

    What can you say about this:i have a browser-enabled form with managed code which simply adds content of one field to another.But each time i’m clicking the button to perform this action i get this message:"An entry has been added to the Windows event log of the server".

    Log ID:5337.

    My code is just this:

    XPathNavigator xNavMain2 = this.MainDataSource.CreateNavigator();

    string string1 = xNavMain2.SelectSingleNode("//my:Comments", this.NamespaceManager).Value;

    string string2 = xNavMain2.SelectSingleNode("//my:Add_comment", this.NamespaceManager).Value;

    xNavMain2.SelectSingleNode("//my:Add_comment", this.NamespaceManager).SetValue("");

    xNavMain2.SelectSingleNode("//my:Comments", this.NamespaceManager).SetValue(string1 + "n" + System.DateTime.Now + " " + string2);

    What should i do to get rid of this error?

    Vitaly

  100. infopath says:

    Hi Vitaly,

    You need to determine what is failing for you. This code works fine in my testing so I would suggest you either see if there is any relevant information in the Application Event log or enable Verbose logging for the various Forms Services categories, reproduce the error and then check the ULS logs on your SharePoint server to see if these point to the cause of the problem.

    Have you tried running this in the InfoPath client? Does it fail there as well?

    Scott

  101. irgendwo says:

    Hi Scott

    Got that problem fixed,thanks.It was security issue i think.After setting full trust mode and creating trusted certificate that code worked.

    Scott,what should we do if we want to run some code on client machine?The only available way i see is to save the form in source files and then insert javascript code in,manifest.xsf.Haven’t tried it yet,though.Is it really possible?Maybe there are other more friendly ways?

    Vitaly

  102. infopath says:

    Hi Vitaly,

    As you know with a form opened in the browser, all managed code will execute on the server. I have no idea if modifying the manifest as you have described will work; however, it would not be supported.

    As you probably know you can create a custom ASPX page that hosts the XmlFormView control to display your InfoPath forms – there may be some way to get client side script to run from that ASPX page but I am not sure about that.

    Scott

  103. liga says:

    hey,

    I’m fairly new to form services.. maybe you can shed some light on this.. I’d really appreciate that. The questions are serious :-)

    1. save to "this" sounds promising. But somehow "SaveLocation" is an unknown key in my dictionary. Now I happen to know there’s a SaveLocation Property for XmlFormView. But setting that property doesn’t really help. So how am I supposed to open forms carrying along this parameter? Thinking about that.. if I still have to set the parameter manually there’s no gain here, is there?

    2. And as you have to publish the form template to the "Form Templates" library I cannot see how saving to "this" library actually makes sense anymore :-/ Don’t you typically want to open the form from the forms library and then store filled out forms to another library?

    I’m currently looking for a way to open, save and close within a aspx site automagically. For opening purposes I use the XmlFormView control. The saving part is where I’m stuck right now. Among choosing the right library I also need a way to create unique (filled out) form names. Now() doesn’t sound not really promising. Any way I can have GUIDs here?

    Again, help is much appreciated!

    Thanks in advance

  104. infopath says:

    Hi Liga,

    Let me try to address each question:

    #1: See my response to a question on January 2nd – it has modified code.

    #2: First of all, you do not actually "publish" to the Form Templates library. That is a special library that is used when you "Admin" deploy a form template. So the short answer to this is: yes – you want to determine where this form was opened from so you can dynamically determine where to submit the completed form. This is what this sample demonstrates.

    #3: Are you using a custom ASPX page for any special reason? Does the built-in FormsServer.aspx page not provide what you need? At any rate – yes, you can use a GUID to create unique names but you would need to do this in code. There are certainly other options as well:

    – Use a combination of fields from your form template

    – Use code (or a web service) to pull a unique number from a database (i.e. SQL Server)

    – Use a web service to generate and return a random number or GUID – this would eliminate the need to do this in code behind your form template

    Scott

  105. liga says:

    Thanks for your reply, Scott :-)

    @3: Yes. Special reasons being: The form has to be shown in the context of a website. We do not want to open a new window. I already tried assigning a GUID but as it turns out Filename is a read-only property (on FileSubmitConnection). But as I’m still struggling with all the "dynamically save to library x" part I didn’t really look into that yet. Any directions you can point me to?

    @2: Yes, I understand that. But still you open the form directly from that "special" library don’t you? (no matter if you use formsserver.aspx or some custom.aspx site with a xmlformview control)

    So let’s assume I have 10 different forms in my forms template library. Doesn’t each and every one have the same "Request url"?

    It would make sense if you had a webpage in a library (let’s say "NovemberForms" and within that page open a form from the forms template library and save that to novemberforms library. Much like reading the Request object in asp.

    On a side note.. are there forums I can turn to?

  106. infopath says:

    Hi Liga,

    The point of the code in this sample is this: let’s say you publish a browser-compatible XSN and want to use this in multiple document libraries. With the out of the box functionality, when you setup a "submit" connection to allow the user to "submit" the completed form, it can only submit to the library which you setup at design time. With this sample, it dynamically determines the library from which the form was launched so it submits the completed form to that library.

    Now, maybe where the confusion is coming in is this: you are correct that when you "Admin" deploy an XSN, the resulting (uploaded and activated) XSN resides in a special "Form Server Templates" library; however, this is *not* where you want to use this form. What you should be doing is creating other libraries where you want to use that XSN, setting the "Allow management of content types" to Yes for those libraries and then adding that XSN from the Content Types list to that library.

    Scott

  107. liga says:

    Great! It all makes sense now :-)

    Oh and there’s a SaveLocation parameter in the url now, so that’s working, too. *happy*

    Unfortunately another part of my solution broke apart while switching to the new multi-purpose library.

    I can’t open the new form within an XmlViewControl (within my webpart) anymore.

    I set XsnLocation to the url I get when creating a new form from my library.

    "The following file is not a valid InfoPath form template"

    http://forms.domain.tld/_layouts/FormServer.aspx?XsnLocation=http://forms.domain.tld/FormServerTemplates/SampleSimpleFormWithCode.xsn&SaveLocation=http://forms.domain.tld/test.

    Opening the form directly (without xmlformview control) works perfectly fine.

  108. infopath says:

    Hi Liga,

    Glad you are making progress! In regard to the XmlViewControl, have you tried setting the XsnLocation to this:

    http://forms.domain.tld/FormServerTemplates/SampleSimpleFormWithCode.xsn

    Scott

  109. liga says:

    Hi Scott,

    I tried that. As soon as you add any additional parameters to the XsnLocation property the XmlFormView fails to load the form.

    If I omit the SaveLocation parameter.. guess what.. KeyNotFoundException :-)

    So I guess I’ll have to specify the target library prior to deployment rather than figuring it out dynamically :-(

  110. infopath says:

    Hi liga,

    I have never used the XmlView control (I am assuming this is a SharePoint web part?) so this may not work as you need.

    Scott

  111. Waltervonallmen says:

    Hi,

    I’m trying to use this "How to" with Infopath 2010 and SPS 2010, but I always get following error :

    The InfoPath formular could not be transmitted.

    The eventhandler for "OnSubmitRequest" doesn’t work correctly.

    The objectlink was not specified to a objectinstance.

    onTestForm_web.FormCode.FormEvents_Submit(Object sender, SubmitEventArgs e)

    on

    Microsoft.Office.InfoPath.Internal.FormEventsHost.OnSubmit(DocReturnEvent

    pEvent)

    on

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

    (Info: The first three sentences of the message were translated by myself

    (from german to english))

    Any ideas?

    walter

  112. infopath says:

    Hi Walter,

    I just tested the exact steps in the blog with InfoPath 2010 and SharePoint 2010 and they worked without any modification whatsoever. Now, I did test opening the form in the browser…is this how you tested? If so, did you follow the steps in this post exactly as they are documented?

    Thanks…

    Scott

  113. Waltervonallmen says:

    Hi scott

    Thanks for your answer!

    Yes! I followed all the steps which have to be taken in the tutorial. I wasn’t able to test the form in the browser, cause I’m currently using 2008 server R2 in German and all the rest (SPS, Infopath,…) in beta (so in english). Thats the reason I can’t use InfoPath WebApps at the moment..So I have to test the form with a localy installed InfoPath 2010 beta.

    The test procedure I’ve done:

    1. upload the form into a form library (manually)

    2. open and fill out the form

    3.  click submit -> the upper error occurs! :(

  114. infopath says:

    Hi Walter,

    Hmmm…this still works for me…so first concern is your comment: "upload the form into a form library (manually)".

    Not sure what you mean by that but what you should be doing is "publishing" the XSN from within InfoPath and, for testing purposes, let the publishing wizard create a new library for you. If you are indeed just using the SharePoint "upload" functionality to upload the XSN to a library, this will not work in many ways. :)

    When you publish the XSN to your SharePoint site as I have described above you should be able to click on the New button and get a new instance of the form. If the code is working as designed, the 3 text boxes on this sample form will already be completed with the correct information about where the form was published and opened.

    Scott

  115. Waltervonallmen says:

    Hi Scott

    Thank you! Now It’works!:)

    I didn’t publish the form template but uploaded it! That was the point I misunderstood :(

    Scott, I got another question…

    I should publish an infopath form template to serveral different libraries in different team sites on one sharepoint server.

    Is it possible to automate the publishing procedure? (ps script?)

    Walter

    ps: I currently creating those team sites including their document libraries by using a powershell script.

  116. infopath says:

    Hi Walter,

    Glad you were able to get it working!

    In regard to publishing – the InfoPath designer does not have an object model so there is really no way to automate this. However, have you considered publishing the XSN as a "Site Content Type?" When you do this, instead of publishing to a specific library you "publish" the XSN to your site and "store" it (the XSN) in a library you create (i.e. MyContentTypes.) Then once you have published the XSN as a "Site Contene Type" then you can add that XSN to any library in that site collection. To do that:

    – Create a library where you want to use the XSN

    – From the Settings button, choose Form (or Document) Library Settings

    – Click Advanced Settings

    – For Allow Management of Content Types, choose Yes and click OK

    – You will now see a "Content Types" section with either a default Form or Document content type – click Add from existing site content types

    – Select the XSN you published as a Site Content Type, click Add and then OK

    – Click on the default Form or Document content type that was there by default and then click Delete this content type (all that does is remove the default type from this library)

    Now when you click New you get a new instance of your XSN just as if you had published it but now you add the added benefit of being able to use that XSN in other libraries in this site collection. :)

    Scott

  117. Waltervonallmen says:

    Hi Scott

    Thank you for your detailed explanation about publishing forms! In fact, that is exactly what I need!

    Is it possible to automate the following few steps?

    – From the Settings button, choose Form (or Document) Library Settings

    – Click Advanced Settings

    – For Allow Management of Content Types, choose Yes and click OK

    – You will now see a "Content Types" section with either a default Form or Document content type – click Add from existing site content types

    – Select the XSN you published as a Site Content Type, click Add and then OK

    – Click on the default Form or Document content type that was there by default and then click Delete this content type (all that does is remove the default type from this library)

    ..if so, which classes do I need for each step above?

    Walter

  118. infopath says:

    Hi Walter,

    Honestly I don’t know if there is a way to do this…this functionality is all SharePoint and that is not my area of expertise. You may want to ping a SharePoint forum and see if there is some code you could execute to modify those settings.

    Scott

  119. Waltervonallmen says:

    Well, I will looking for those information in a sps forum!

    But anyway I’d like to thank you for supporting me!

    Walter

  120. infopath says:

    My pleasure Walter!

    Take care,

    Scott

  121. Waltervonallmen says:

    Hi Scott

    I got a little question about submitting a form to a sps document library.

    I publish my forms as content types at the root of the site collection. After filling out one of these form templates I’d like to submit this form to a specific doc library in the same site collection, the URL of the appropriate library is depending on a string in a textbox.

    So I have to add a submit dataconnection programmatically, however I don’t have a clue how to do that?

    Walter

  122. infopath says:

    Hi Walter,

    So that you know, InfoPath does not have an object model for the designer whatsoever so "adding" a data connection at runtime is not possible; however, changing an existing data connection at runtime is possible and that is what this blog post is for. But if you have tested (or gone through the comments in this blog) you have seen that if you publish the XSN as a Site Content Type *and* are opening the form in the InfoPath client then there is no way to capture the location of where the form has been opened. We have had this request a number of times but it is not possible to capture that information…unless you open the form in the browser.

    Scott

  123. KCD75 says:

    Hi Scott,

    First, thanks!  Your example worked as expected in SP2010 (even works with Document Sets.)  Although, I'm hoping that you're able to provide insight for a problem that I'm encountering.  After the form is submitted to the "this" library/location, I get an error when I re-open the form and the following is logged to Windows Event Log:

    Source: InfoPath Forms Services

    Event ID: 5337

    Task Category: Runtime – Business Logic

    Type: KeyNotFoundException

    Exception Message: The given key was not present in the dictionary.

    Any ideas?

    Thanks!

    Thomas

  124. slheim says:

    Hi KCD75,

    Glad it worked for you. :)

    When you get the error are you opening the form in the InfoPath client or in the browser?

    Also – can you post the actual code you have on the loading event?

    Thanks,

    Scott

  125. Waltervonallmen says:

    Hi Scott

    I got the same error message (5337 in the event log) as KDC75, each time I'am reopening a form. Here you got my loading method:

    public void FormEvents_Loading(object sender, LoadingEventArgs e)

           {

                   //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 is not necessary –

                   //this is simply to see the process in action

                   PopulateLibInfo(OpenedInBrowser);

           }

    Walter

  126. Waltervonallmen says:

    .. oh I get the error message in the browser.

  127. Scott Heim says:

    Hi KDC75 and Walter,

    The error you are getting was due to a bug <g> in my original sample code. Take a look at the January 2 comments on page 5 – here I have updated code to correct that error.

    Scott

  128. Abdul says:

    Thats a good tutorial. Can I have a a similar solution for creating a  Receiving data connection from a Sharepoint list?

  129. Scott Heim says:

    Hi Abdul,

    Are you referring to how to dynamically create a receive data connection to a SharePoint list? If so – I don't know of a way to do this as InfoPath actually uses the GUID to the list as part of the receive data connection so it is not as simple as just knowing what URL the XSN was opened from.

    Scott

  130. jposte says:

    Hi Scott,

    You say to Walter in April 2010:

    … if you publish the XSN as a Site Content Type *and* are opening the form in the InfoPath client then there is no way to capture the location of where the form has been opened.

    If you double click an InfoPath Form that was published as a Content Type in a SharePoint Form Library, then in FormEvents_Loading if you use the statement:

    string formUrl = this.Uri;

    formUrl will contain the total URL for where the form was opened from.

    If you do this on a form you opened with NEW it will contain a suggested form name such as Form1.

    If you do it from Preview or Debug mode it will contain (Preview) Form1.

    I use this technique to retrieve the form URL at runtime so that I can tell where it came from to use as necessary in program logic.

    Jeff

  131. Scott Heim says:

    Hi Jeff,

    Thank you for the information. I believe in most cases, users will add the Content Type to the library and click New, which will not give the same information.

    Scott

  132. Cat says:

    Is there a way to submit a form to a folder on the computer rather than a URL?

  133. Meri says:

    Hi,

    I'm having a problem publishing my form to a content type. I made the form full trust created a cert to sign it, but my only option when publishing is to make it administrator-approved. Do you have any idea why that might be?

    Meri

  134. Scott Heim says:

    Hi Meri,

    Yes – this is expected when you form template is browser-compatible. Once you set the security level to Full Trust and you have a browser-compatible form, the only SharePoint publishing option you will have is as an Administrator-approved form template. However, once you complete the entire process, you *will* wind up with a SharePoint Content Type that you activate to a site collection and then add to a library.

    Take a look at this link:

    technet.microsoft.com/…/cc262921.aspx

    It is written for InfoPath and SharePoint 2010 but if you are using 2007 the steps are basically the same.

    Scott

  135. Anita says:

    Hi Scott,

    I am trying to get this exact functionality work on Infopath 2010 integrating with Sharepoint 2010. I have a admin approved, browser enabled form which I installed using Central admin. But I want the form to be submitted using a custom button.I added a button, named it submit and onClick event of button I added the code that you have in your form submit event.

    The values in the text box fields appear correct, but when I try to submit,

    I keep getting exceptions something like this.

    Is there something I am missing? I don't have my form digitally signed. Is this an issue.

    Appreciate any response.

    Business logic failed due to an exception. (Type: InvalidOperationException, Exception Message: The given key was not present in the dictionary. The given key was not present in the dictionary.) 7b141a58-0563-4801-9e99-128bac7d3102

    01/31/2011 14:01:32.02 w3wp.exe (0x1A0C)                       0x17B0 InfoPath Forms Services       Runtime – Business Logic       7tge Medium   Exception thrown from business logic event listener: System.InvalidOperationException: The given key was not present in the dictionary. —> System.Collections.Generic.KeyNotFoundException: The given key was not present in the dictionary.     at System.ThrowHelper.ThrowKeyNotFoundException()     at System.Collections.Generic.Dictionary`2.get_Item(TKey key)     at Microsoft.Office.InfoPath.Server.DocumentLifetime.DataAdapters.EnsureDataAdapter(String name)     at Microsoft.Office.InfoPath.Server.DocumentLifetime.DataConnectionCollectionHost.<>c__DisplayClass4.<get_Item>b__3()     at Microsoft.Office.InfoPath.Server.DocumentLifetime.OMExceptionManager.ExecuteOMCallWithExceptions(OMCall d, ExceptionFilter exceptionFilter)     — End of inner exception stack trace —     at Microsoft.Office…. 7b141a58-0563-4801-9e99-128bac7d3102

    01/31/2011 14:01:32.02* w3wp.exe (0x1A0C)                       0x17B0 InfoPath Forms Services       Runtime – Business Logic       7tge Medium  

  136. Anita says:

    Hi Scott,

    I did not create the dummy Library and that was why I was getting this error. Now the form is submitted perfectly. But when I try to open, while opening it throws the same exception as above. Not sure why is that. On my form load event, I have the method you have to populate the strlocation etc.And then I have few of my other logic.

    Any ideas?

  137. Scott Heim says:

    Hi Anita,

    If you followed the code in the original post, I believe I had a "bug." :) Take a look at the updated code I provided in my 2 Jan 2008 2:17 PM comments and see if this resolves the issue.

    My apologies for the inconvenience…

    Scott

  138. Anita says:

    Perfect Scott..That worked great.

    A very useful blog I have to say!!

  139. Nik Patel says:

    Do I really need to digitally sign the infopath forms with the code? I am deploying the Infopath 2010 forms to the SharePoint using administrator approved method? I have set the forms to full trust but wondering if I really need to set the digital certificate?

  140. Scott Heim says:

    Nik – if the InfoPath form will *only* ever be used in the browser then no – you don't have to digitally sign the XSN. However, if the security level is explicitly set to Full Trust and there is a possibility it will be opened in the InfoPath client, then you will need to sign it.

    Scott

  141. Surya Padala says:

    Hi Scott,

    Thanks for the code. We are using infopath 2003, used 'SubmitToThisLib_2003_js.txt' script and working as expected. As per my understanding this code helps to submit the "InfoPath form template" to multiple SharePoint document library's dynamically. But we need to publish the infopath template to multiple SharePoint document library's right?. Can we avoid this multilple Publish in infopath 2003?

  142. Scott Heim says:

    Hi Surya,

    To clarify – the code allows you to submit the completed InfoPath form to the library from which it was opened without knowing that library at development time. It does *not* submit the InfoPath Form Template – this is something that is published and you *must* publish the XSN to each library…there is no way around this. In fact, this behavior is the same in all three versions of InfoPath: 2003, 2007 and 2010.

    Scott

  143. Surya says:

    Hi Soctt,

    Thanks for your quick responce. This code is working when we Enable the Submit functionality (Tools | Submit Options) and choose the “Perform custom action using code” option.

    In our case we have a Button for submit and it has some rules before submiting the form. How can we enable this functionality for submit button with out "Enable the Submit functionality"

  144. Scott Heim says:

    Hi Surya,

    You will need to move the logic you have in the "rules" to the code. If all the rule logic is met, then proceed to submit the form.

    Scott

  145. Sune says:

    Hi, would the updated code you used on 2 Jan 2008, allow it to work with the forms library having subfolders and check in / check out functionality turned on?

    As it is now, whenever a form is submitted from within a subfolder an exact replica is created in the root of the forms library.

    We are using 2003 C#

  146. Scott Heim says:

    Hi Sune,

    I just tested this and am not seeing the behavior. Now, I did just a simple test and used C# for 2007 so you will need to change this for 2003:

    – Added a new node to my XSN called: strSubFolder (for this simple teste, I did NOT write any code to populate this node when the form opens)

    – Added strSubfolder to my View so I could enter a value in that control

    – Made the following changes to the "submit" code:

        – Added this line of code where I created the other XPathNavigator objects:

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

        – Modified this code from this:

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

        // xnLocation and xnFolderName values

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

        To this:

        if(xnSubFolder.Value != string.Empty)

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

        else

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

    – Publish the changes

    – Open a new instance of the form in the browser and submit – result: just one copy in the folder – no where else

    – Re-open that form in the browser and submit again – result: again, just the one copy in the folder – no where else

    So it seems I am not able to reproduce your issue. You may want to either debug that code or add tracing statements to your code to see if there is something in the code that causes this to occur.

    Scott

  147. Neil MG says:

    This is kinda working for me (submitting an Infopath 2010 Browser enabled form to a Sharepoint 2010 Document Set) when first submitted, but on subsequent submissions it's failing. I've used the revised code from the 2nd January post but it's still not working:

    strFormURL:

    First Run: http://server/doc library/docset/

    Second Run: /doc library/docset/form name

    strLocation:

    First Run: http://server/doc library

    Second Run: http://server

    strFolderName:

    First Run: docset

    Second Run: doc library

    I'm not a programmer and am quite possibly an idiot (I bet it's a schoolboy error), so go easy on me!

    Thanks in advance for any help – much appreciated!

  148. Shyam says:

    Hi Scott,

    Thanks for the blog! I used your same code. There was no error. However, when I publish and test it, I get the following msg:

    The given key was not present in the dictionary.

      at System.ThrowHelper.ThrowKeyNotFoundException()

      at System.Collections.Generic.Dictionary`2.get_Item(TKey key)

      at Microsoft.Office.InfoPath.Internal.DataConnectionsHost.get_Item(String name)

      at Stakeholder_checklist_final.aspx.FormCode.FormEvents_Submit(Object sender, SubmitEventArgs e)

      at Microsoft.Office.InfoPath.Internal.FormEventsHost.OnSubmit(DocReturnEvent pEvent)

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

    I m not sure what seems to be the problem. Please help

    Thank you,

    Shyam

  149. Scott Heim says:

    Hi Shyam,

    I really have no idea since I don't know where the failure occurs. It could be that one of the fields is  not populated? Does it work in the InfoPath client? If it does and only fails in the browser then you will need to debug the code when it runs in the browser – take a look at this for how to debug browser code:

    blogs.msdn.com/…/debugging-browser-forms.aspx

    Scott

  150. SP says:

    Does the DummyLib need to be created on the site to get this code to work.

  151. Scott Heim says:

    Hi SP,

    If you are using InfoPath 2010, then yes – the "dummy" library needs to exist as InfoPath now validates that the submit to library is there. As such, you could just use any default library that would normally be there, such as "Shared Documents".

    Scott

  152. Hi Scott, says:

    I am so new to this. I already created my form. I am not sure how to place the codes. Can you help, please.

    Neetu

  153. Neetu Wong says:

    Scott,

    I am using infopath 2010, I have already deployed my form to sharepoint but having trouble getting it onto my website. Help!

    Neetu

  154. Scott Heim says:

    Hi Neetu,

    This particular blog post is fairly code intensive…you need to have some idea about programming to be able to maintain your code once you follow these steps. If you don't have that, it's going to be very difficult to implement changes, updates, etc. The post itself documents where to add the code.

    In regard to your question about having trouble getting the InfoPath Form Template to your web site, you are going to need to provide more detail as I don't know what you are referring to. Did you publish the Form Template (XSN file?) Did it produce an error or publish successfully? It sounds like you are new to InfoPath – if so, you may want to go through this training before going any further with this post:

    InfoPath 2007 Training Labs

    office.microsoft.com/…/HA102227501033.aspx

    InfoPath 2010 Training Labs

    msdn.microsoft.com/…/gg180739.aspx

    Scott

  155. Dino says:

    Hi Scott,

    Great post!  Especially considering that this post is over 5 years old and is still very relevant.  It's gotten me to almost where I want to be.  

    I have a SharePoint 2010 web part which hosts a XmlFormView control.  I use this control to render an Administrator-approved InfoPath 2010 browser-enabled form.  This form has custom code for the Loading and Submit events.  I've verified that they both work if I submit the form using the Submit button from the SharePoint ribbon.

    Now, I need to be able to call the Submit event of the form via an ASP.NET button.  This is because I need to process other information together with the data in the InfoPath form.  This is were I'm having trouble.  Calling the Submit (XmlFormView.XmlForm.Submit()) method yields me an InfoPathFatalException exception.  It doesn't even step into the Submit coe I wrote for the InfoPath form.  Just to test and make sure that the form still works, I've kept the Submit button in the SharePoint ribbon visible.  I can debug and step into the Submit code.

    I've checked various sources in the internet and have yet to find a working sample of calling the InfoPath form's Submit method from an ASP.NET button.  Is this even possible?

    Hope you can help.  Thanks!

    Dino

  156. Scott Heim says:

    Hi Dino,

    Glad this post has helped! Unfortunately you cannot directly call a "submit" or a submit connection from a hosted page. However, there is a way you can still do this:

    – Create a .NET web service that takes, as a minimum, the name for the "submitted" form and the XML from the form

    – From your custom ASPX page, call that web service passing the information from the form

    Here is some sample code:

    NOTE: THIS IS NOT PRODUCTION READY!! IT IS INTENDED AS A SAMPLE ONLY!! **

    Here is a sample web service:

    //You will need to change the code to reference your library name and your site URL

    [WebMethod]

    public void UploadDocumentToLibrary(string formName, string formXML)

    {

    //NOTE: If running this anonymously, the "RunWithElevatedPrivileges will be

    //needed to allow the process to complete.

    SPSecurity.RunWithElevatedPrivileges(delegate()

    {

    string libraryName = "YourLibraryNameForSubmittedForms";

    SPSite site = new SPSite("http://serverName&quot;); //Or servername/site

    SPWeb web = site.OpenWeb();

    web.AllowUnsafeUpdates = true;

    SPFolder folder = null;

    //See if the library exists – if not, catch the error

    //and create that folder

    try

    {

    folder = web.Folders[libraryName];

    }

    catch (Exception)

    {

    //Library did not exist, so we create it and add it to the Quick Launch

    SPListTemplateType t = new SPListTemplateType();

    t = SPListTemplateType.DocumentLibrary;

    Guid listGuid = web.Lists.Add(libraryName, "", t);

    SPList newList = web.Lists[listGuid];

    newList.OnQuickLaunch = true;

    newList.Update();

    folder = web.Folders[libraryName];

    }

    //Build our URL for the form

    string fileUrl = folder.Url + "/";

    //See if the user added ".xml" to the file name

    //If not, we will want to add it

    if (formName.IndexOf(".xml") > 0)

    fileUrl += formName;

    else

    fileUrl += formName + ".xml";

    //Set the encoding

    System.Text.Encoding e = System.Text.Encoding.UTF8;

    //Create a byte array from the XML string

    byte[] b = e.GetBytes(formXML);

    //Create the file in the specified library

    SPFile file = folder.Files.Add(fileUrl, b, true);

    }); //Closing for RunWithElevatedPrivileges

    }

    Then from my custom ASPX page, I can call this web service like this:

    protected void Button1_Click(object sender, EventArgs e)

    {

    try

    {

    this.DataBind();

    XmlNamespaceManager ns = XmlFormView1.XmlForm.NamespaceManager;

    XPathNavigator xnMain = XmlFormView1.XmlForm.MainDataSource.CreateNavigator();

    //My web service was called: CreateFormFromXML – so this line needs to be whatever

    //the name is for the web service created above

    CreateFormFromXML svc = new CreateFormFromXML();

    //There is just one public method in the web service: UploadDocumentToLibrary – call this

    //passing in whatever you need to create the form name and the "OuterXml" of the loaded form

    svc.UploadDocumentToLibrary(xnMain.SelectSingleNode("/my:myFields/my:field1", ns).Value.ToString(), xnMain.OuterXml.ToString());

    }

    catch (Exception ex)

    {

    Response.Write(ex.Message);

    }

    }

    When I tested this in my environment, the form was created appropriately in the library. :)

    Hope this helps Dino!

    Scott

  157. Dino says:

    Hi Scott,

    It's been a few days and I haven't seen my post, so I think it might not have gone through when I submitted.

    Anyway, the approach you suggested won't work for my scenario because I need the form's validation to fire.  It won't if I just upload the Xml file into the library.  In fact, this is my current implementation.

    Since I can't call InfoPath's Submit, I'll split my form into 2 pages as a workaround.  1 page for the ASP.NET controls and another for InfoPath.  The user will then access the form as if he/she were running a wizard, with step 1 being the ASP.NET page and step 2 being the InfoPath form.  

    Thanks!

  158. BGM says:

    Hello!  I think you forgot a brace in your property set:

    private object _strUri

    {

     get { return FormState["_strUri"];   <—-should be a brace here, no?

     set { FormState["_strUri"] = value; }

    }

  159. Gennady Vanin ((Novosibirsk) - Геннадий Ванин (Новосибирск) says:

    There is no need of setting the Security Level of the form to Full Trust and signing the form template with a digital certificate if to convert "Main submit" data connection to UDCX file connection having stored it in a data connection library on the same sharepoint site collection

  160. Scott,

    The problem I have is that I am not able to update an existing form (form based not browser enabled). But here is a twist, if I wait for about 15 mins then I open the form I am able to update and Submit.

    Here is the error

    InfoPath cannot submit the form.

    An error occurred while the form was being submitted.

    The form cannot be submitted to the following location: http://salessourcetest/teamsites/ccmtform/Form/123451234123213.xml

    The specified location cannot be accessed. Check that the location you entered is correct and that you have appropriate permissions.

      at Microsoft.Office.InfoPath.Internal.MomExceptionHelper.ExecuteDataConnectionAction(XmlFormHost formHost, OMCall d)

      at Microsoft.Office.InfoPath.Internal.FileSubmitConnectionHost.Execute()

      at CMTInfoPath.Code.FormCode.SaveToSharepoint()

      at CMTInfoPath.Code.FormCode.Button1_Clicked(Object sender, ClickedEventArgs e)

      at Microsoft.Office.InfoPath.Internal.ButtonEventHost.OnButtonClick(DocActionEvent pEvent)

      at Microsoft.Office.Interop.InfoPath.SemiTrust._ButtonEventSink_SinkHelper.OnClick(DocActionEvent pEvent)

    I replace the Submit with "Custom Action" and put in the code you provided. It's not reaching the Submit event handler. But if I wait for 15 mins it works fine. So bottom line its nothing to do with Submit action

    Appreciate your help on the same.

  161. Scott Heim says:

    Hi Cheemalapati,

    It sounds like the form/data is being locked. Unfortunately this could be any number of things causing this and troubleshooting that in this blog would not be beneficial. I would suggest you enable Verbose logging on the server, reproduce the issue and see if this points you to what may be the underlying cause. If not, then you will want to open a support case to have a support engineer dig into this with you.

    Scott

  162. Muayad Rawashdh says:

    How i can Know if the user open a new form or open existing form?

  163. Scott Heim says:

    Hi Muayad,

    If you are *not* using code then you would need to check if a field you know would always be empty on a new form and *always* completed on an existing form. If you are using code then you can do this:

    //C# sample

    if (this.New)

    {

    }

    else

    {

    }

    //VB sample

    If Me.[New] Then

    Else

    End If

    Scott

  164. Tom Hansen says:

    Hi Scott,

    It's amazing that your post is still very relevant all of these years now. Thank you for all of the work you've placed into this post and updating it periodically.

    I have implemented your code (in addition to the modifications within the comments for opening existing forms) into my XSN. There was a question asked several years ago about an error dealing with ArgumentOutOfRangeException: Length cannot be less than zero. However, I don't believe the OP ever responded to your queary. And unfortunately, I am having the same issue as the OP. The error I am receiving involves the following line of code:

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

    I am publishing the form to a content type within my site. I'm not getting any errors during the build. However, when I test the form, the error appears while the form is loading.

    Would you have any direction on how to resolve this issue?

    Thanks!

    Tom

  165. Scott Heim says:

    Hi Tom,

    What I would do is either add logging to the code or, even easier, just add a new text box to your form and just before the code that fails, set the value of the node the text box is bound to: strPath – this will show you what is in that variable which should point you to what is causing the error.

    Scott

  166. Tom Hansen says:

    Thanks for the insights, Scott. I'm going to do what I can to track down the issue.