Submitting to a Database (via Web Services) in InfoPath Forms Services

If you've ever designed and deployed a form that will be frequently used or require significant data analysis, you have probably looked into maintaining data in a SQL database.  With InfoPath 2003 and the InfoPath 2007 rich client, you get what you expect.  You create a main database data connection to the SQL server and pick tables and columns that meet the requirements for submit functionality.  When you open your form and click the "Run Query" button, you see the data pulled from the database as you'd expect.  You then happily insert, update, or delete records and, when the time is right, hit "Submit".  Luckily for you, the InfoPath client took care of maintaining the list of changes that you made while editing your form.  With this list of changes intact, your updated data streaks back to the database to await the next query.

Enter InfoPath Forms Server... Here we don't get the change tracking for free, so we'll need to do some work to simulate change tracking outside of the form's execution.  Basically, what we're going to try to accomplish is to use an intermediate web service that will handle querying and submitting the data from and to the target database.  The web service will timestamp the data at query time and send the data to the form for editing.  Then the form filling user will edit the data and click "Submit".  When the data arrives back at the web service, we need to figure out what changed in the meantime.  This means that we'll have to check to see if anything has changed in the database since the time when we queried the data.  If it has, then the submitted data should be rejected and the user should re-query before re-applying her edits.  If it hasn't, we'll diff the submitted data with the database data and submit the difference back to the database!  Let's get started!


Create the Web Service and Setup the Database

Since the InfoPath data connection wizard is easiest to use when your web service is already established and available, let's start with creating the web service and setting up the database.

1) Download the attached archive and extract it somewhere on your hard drive

2) Create a new web site in Internet Information Services (IIS)
NOTE:  IIS must be enabled as a Windows Component through "Add or remove Windows components" in the "Control Panel")

  • Launch IIS ("Start" >> "Run", type 'inetmgr')
  • Right-click the "Web Sites" node and select "New" >> "Web Site…"
  • Click "Next >" on the first page of the wizard.
  • Type a name for your web site (e.g., "IPFSDiffGram") and click "Next >"
  • Type a unique port number (referred to, hereafter, as '<portNum>') for the web site and click "Next >"
  • Enter the path to a folder where the site contents will be stored and click "Next >"
  • Check "Read" and "Run scripts (such as ASP)" permissions and click "Next >"
  • Click "Finish".
  • You may want to create a new Application Pool for this web site "to make your server more efficient and reliable".

3) Create the web service

  • Launch Visual Studio 2005.
  • Click "File" >> "New" >> "Web Site…"
  • Select "ASP.Net Web Service" in the "Visual Studio Installed Templates" section.
  • In the "Location" drop-down, select HTTP and then click "Browse…"
  • Select the Web Site created in step 1 and then click "Open"
  • Click "OK" on the "New Web Site" dialog

4) Add the code and service asmx files to the project

  1. Open the Solution Explorer task pane (click "View" >> "Solution Explorer")
  2. Right-click the top-level project icon (labeled http://localhost:<portNum>) and select "Add Existing Item…"
  3. Navigate to the "DiffGramService.asmx" file and then click "Add". Refer to the files you downloaded for the contents of this file.

  4. Right-click the "App_Code" icon and select "Add Existing Item…"
  5. Navigate to the "DiffGramService.cs" file and then click "Add". Refer to the files you downloaded for the contents of this file.

5) Customize the web service code for your database

  1. Instance variables

    1. DBConnectionString -- The connection string to connect to your database.
    2. DBTable -- The name of the table to which the web service should connect.  The table must feature a surrogate single-column primary key with an integer data type.
    3. ColumnNames -- An array that contains the names of the data columns in your database.

  2. WebMethod query parameters

    1. DBData(parameter_list)

      • parameter_list should be the columns, with appropriate System.Types to match your database
      • You'll need to specify the appropriate SqlDbTypes that correspond to the columns in your database

    2. UpdateDBData(DataSet, parameter_list)

      • Do not change the DataSet parameter
      • parameter_list should be the columns, with appropriate System.Types to match your database
      • You'll need to specify the appropriate SqlDbTypes that correspond to the columns in your database

6) Create the database table and DML trigger
The web service includes logic to update the database table and create a DML trigger to maintain a timestamp of Last Update for each record.  However, you may want to create the timestamp column and trigger yourself.

  • Example SQL script to create a database named "DBTable" that is compatible with this web service is in the attached files, named "CreateDBTable.sql". The table will have a structure similar to the following:

  • Example SQL script to create a DML trigger that will maintain the timestamp of last update for each record is also attached, and called "CreateDMLTrigger.sql".

7) Build the Visual Studio solution and publish the web site


Design the InfoPath Form Template

Now that we've setup our database and constructed our web service to do the querying and submitting for us, it'll be a breeze to design an InfoPath form template based on the web service.

1) Design a new, browser-enabled form template, based on the web service that will query/submit the DataSet.

  1. Launch InfoPath and select "Design a Form Template…" on the "Getting Started" dashboard dialog.
  2. Check "Enable browser-compatible features only" (required only for browser-enabled form templates)

  3. Select the "Web Service" icon and click "OK".
  4. Select "Receive and submit data" and click "Next >"
  5. Type the WSDL URL for your web service (e.g., http://<server>:<port>/DiffgramService.asmx?WSDL) and click "Next >"
  6. Select the web method that will return the DataSet and click "Next >".
  7. Click "Next >" on the DataSet change-tracking page.
  8. Click "Next >" to name the query data connection and move on to define the submit data connection.
  9. If the submit WSDL URL is different than the query WSDL URL, enter it here and click "Next >".  Else, just click "Next >".
  10. Select the web method to which the DataSet will be submitted and click "Next >".
  11. Select the DataSet parameter in the "Parameters" listView.
  12. In the "Parameter options" section, click the button next to the "Field or group" field.
  13. In the "Select a Field or Group" dialog that pops up, expand the "dataFields" node until you see the node with the name of the DataSet (it's the parent of the repeating "(Choice)" node).


  14. Select the DataSet node and click "OK"
  15. If your web service takes parameters to constrain the select command, map these parameters to the queryFields generated during the creation of the query connection.
  16. Click "Next >" on the submit parameter mapping page.
  17. Click "Finish" to name the submit data connection and finish the Data Connection Wizard.


2) Set the default values for the "ID" and "QueryTime" fields

  1. In the InfoPath Designer window, click the "View" menu and select the "Data Source..." option.
  2. In the "Data Source" taskpane, expand the "dataFields" node completely.
  3. Double-click the "QueryTime" node to open the properties dialog.
  4. Type "1/1/1900 12:00:00 AM" (without the quotes) in the "Value" field in the "Default Value" section and click "OK"
  5. Repeat steps 2.a-2.c for the "ID" field.
  6. Type "-1" (without the quotes) in the "Value" field in the "Default Value" section and click "OK"


3) Insert the controls into the View.

  1. Click inside the dataFields controls area (it says "Drag data fields here" if you haven't clicked there)
  2. Click the "Insert" menu and select the "Repeating Table..." option.
  3. In the "Repeating Table Binding" dialog, completely expand the "dataFields" node.
  4. Select the group node that has the same name as your database table and click "Next >"
  5. For each of your data columns (e.g., 'Column1', ..., 'Column5'), select the column name on the left, and then click the "Add >>" button to make the column show up in the Repeating Table.

    NOTE:  If you include the 'ID' column, the user will be able to edit the values, and the DataSet may not be validated or merged correctly.
  6. Click "Finish" to accept the repeating table binding and insert the repeating table into the View.

4) Publish the form template to your InfoPath Forms Server

At this point, you have a form template that will work correctly when you open it in the InfoPath rich client.  But this post is all about getting things to work correctly in the InfoPath Forms Server.  So you'll need to configure your data connections to work in the browser by converting the main query and submit data connections to use Universal Data Connection (UDC) files in a Data Connection Library (DCL).  Now you should be all set.  The web service will query and submit the data to the database, and we'll make our best attempt at a diff of the database data against the submitted data.

From here on out, it's up to you.  If you want to, for example, modify the database structure or change the way the trigger works, then you're going to need to modify the web service code.  You'll also need to use "Convert Main Data Source" to update your form template whenever you modify your web service.  You might also want to add support for multiple tables.  All this will take some exploration of ADO.Net DataSets, but it is a reasonable exercise as long as you're comfortable writing managed code.

Forrest Dillaway
Software Design Engineer in Test

Comments (38)
  1. helloitsliam says:

    Loving this post. Keep up the good work!! 🙂

  2. rgardner says:

    Great post.  Everything works great in the InfoPath client, but not from Forms Services.  The form is full trust and is an administrative form.  Both of the data connections are UDC files and I enabled cross-domain data access.  The query works great.  The submit is giving me errors.  Any ideas?  Here is what I see in the SharePoint logs:

    Unhandled exception when rendering form on postback System.IndexOutOfRangeException: Index was outside the bounds of the array.     at Microsoft.Office.InfoPath.Server.SolutionLifetime.WebServiceHelper.HandleSubmitDataSetInput(XPathNavigator inputSubDOM, Boolean[] useDataSets, XmlDocument soapRequest, Solution solution, String name)     at Microsoft.Office.InfoPath.Server.SolutionLifetime.WebServiceHelper.PrepareSoapRequest(XPathNavigator inputSubDOM, Boolean[] inputUseDataset, Solution solution, String name, Boolean useSelf)     at Microsoft.Office.InfoPath.Server.SolutionLifetime.WebServiceHelper.ExecWebRequestSync(XPathNavigator inputSubDOM, Boolean[] inputUseDataset, XPathNavigator resultsSubDOM, Boolean resultUseDataset, XPathNavigator errorsSubDOM, Uri serviceUrl, Uri soapAction, Int…

  3. forrestd says:

    Thanks for your response!  I’m glad to see someone’s trying this out!

    Anyway, as for the error you see on postback, I couldn’t reproduce it with a simple test, so it looks like there’s something about your DataSet that the Forms Server doesn’t like.  It’s possible this has to do with the values you entered into the dataFields, but I’d have to see your source files to diagnose it and see if I could replicate it locally.  On your side, I’d try tweaking the data types of the database column (and modifying the corresponding web service code) to find out if serialization is working correctly.

    I’d love to investigate your failure.  It would be great if you could send me:

    1. A copy of your form template

    2. Your web service code

    3. The asmx file

    4. The 2 sql scripts you used to create your DB table and the DML trigger

    5. Version/SKU information about your Forms Services installation

    6. A description of the data you entered into the form template prior to submitting

    7. Any other environment-specific detail you think is relevant.

    My (clumsily encoded) e-mail is “For[DELETEME – fighting spam]rest[dot]dilla[DELETEME – fighting spam]way [AT] MICROSOFT [DOT] COM”


  4. JSeeders says:

    I am having trouble getting VS 2005 to publish the site.  I keep getting the error "js-forms-webservice:8080/" is not a valid virtual path.  After initially setting the port number to 8080 that path should connect to the IPFSDiffGram directory under wwwroot.  I assume VS connected sucessfully to it when creating the new project.

    I did a little research and found a similar issue noting a VS bug prior to SP1 so I have now updated to SP1 but am still getting the error.  Any ideas?


  5. forrestd says:

    I’m not sure how to reproduce the error you’re seeing, but could you elaborate on the steps you’re following?

    Following these steps, I don’t see any failures:

    1. Create the web site in IIS, with local path set to "C:InetpubwwwrootIPFSDiffGram" and port 4712.

    2. Create a separate app pool for the web site.

    3. Launch VS and create a new web site on local IIS under the site you just created.

    4. Add the cs and asmx files.

    5. Build the project.

    At this point, I can access the web service via the URL: http://localhost:4712/DiffgramService.asmx.

    Are you seeing different results in following those steps?  "Publishing" the web site isn’t strictly necessary when you’re designing the web site on your local server.



  6. Shuwi says:

    Great post, great blog !

    Finally some good / useful information about InfoPath!! 🙂

    I’m running the sample (in exact the same configuration as the sample; same db names etc).

    But I keep getting ‘The exeption: The select command string must start with the ‘SELECT’ keyword!

    I’ve added the selectCommandString to the exeption string so I can see what the commandString actualy is.. and that is: empty..

    throw new Exception("The, " + selectCommandString + ", select

    I’ve looked in the code where the selectCommandString is beeing filled.. but I can’s seem to find it …!

    Thanks in advance!!


  7. cterry says:

    Great – I’m almost there, but getting the same error as rgardner i.e. Index out of bounds when submitting via a browser. Works fine in rich-client!

    I have copied exactly what you had i.e. same db, table, username, password (although I had to change your code which had the columns called data1 etc – changed them to Column1 etc).

    I’m guessing it’s some configuration issue with SharePoint server. Any ideas?



  8. Terry G Phillips says:

    Thank you for the great info.

    If the submit process is an SQL insert, is there a way to return the ID column from the insert procedure and place it in a field on the form?



  9. forrestd says:

    After long absence…

    Shuwi, it looks like you’re using the "DBDataDynamic" WebMethod.  This was my best attempt on short notice to provide a scalable WebMethod that could accept an arbitrary connection string and command, and then query and submit valid recordsets to the database table.  However, for most purposes, it’s a lot easier to just use the "DBData" WebMethod, which takes a static number of query parameters corresponding to fixed columns in your DB table.  Try that one before you dive too deeply…

    Cterry and Rgardner, we’ve achieved an internal repro environment for the IndexOutOfRangeException, so we’ll take a look and see what we can find out.  For now, I don’t have any further info.

    Terry G Phillips, you can get the updated ID by simply executing the query data connection, constraining the recordset by passing queryFields that will return the record you’re looking for.  Then you copy the ID value, using Rules or custom code in your form template, to move it to a target field.

  10. forrestd says:

    Oh, and Shuwi, the strings passed to the web service are populated with the values of the "dfs:queryFields" xml nodes in your form template.  It’s a good idea, when using the dynamic WebMethod, to set a default value for the queryFields to specify the connection string, command, etc.

  11. forrestd says:

    Okay, Cterry and Rgardner, I think we’ve narrowed down the issue on our side.  Shuwi, this affects you as well.


    Map all submit parameters, not just the DataSet:

    Revisit step 15 for designing your submit data connection:  If your web service takes parameters to constrain the select command, map these parameters to the queryFields generated during the creation of the query connection.


    In the screenshot of the submit data connection parameter mapping page in the data connection wizard, I only show the DataSet parameter for the web service.  That screenshot is actually out of date relative to the source for the web service.

    In the attached files, you’ll see that the "UpdateDBData" WebMethod actually takes query parameters, in addition to the data being submitted.  This is to allow the web service to restrict the result set, being queried and successively submitted, to a subset of the data in the table.

    Now, practically, that means you’ll actually see "Column1", …, "Column5" in the data connection wizard.  For browser-enabled form templates rendered in the browser, you must map the other (non-dataset) parameters to their corresponding queryFields.  The rich client can handle it if you don’t map the parameters, and empty strings are sent in place of the queryFields values.  IPFS, on the other hand, requires that the mappings be defined.



  12. xjmmn says:

    Great post.  Everything works well!

    spent a lot of time:)

  13. xjmmn says:

    I receive an error message when I change the data type with int.

    error :"The form can not be submitted because it contains validation errors. Errors are marked with either a red asterisk required fields or a red dashed border(invalid values) "

    Fiedld or group :tns supplier_id

    error: only integers allowed.

  14. forrestd says:

    Excellent responses, everyone!

    1. xjmmn, string fields in InfoPath do not, by default, require a non-empty value.  When you change the data type to int, you’ll need to guarantee that the fields contain an integer value.  Otherwise, you’ll see the data validation errors at submit time.

    2. Bjoern Thomsen and Paresh also pointed out another corner case that needs to be addressed:  After step 2.6, you need to set the default "Choice" for the DataSet to use the "Time" table.  Follow these steps:

       a.  In the InfoPath Designer, click "Tools" >> "Default Values…"

       b.  Expand the nodes until you see the "DBTable" and "Time" group nodes under the repeating "(Choice)" node.

       c.  Select the "Time" radio button to include the timestamp in the form by default.

    NOTE:  After fixing your form template as above, you’ll have to replace line 897 in "DiffGramService.cs" with the following code:

    object maxPrimaryKeyObject = dbPrimaryKeyValuesReader.GetValue(0);

    if (maxPrimaryKeyObject is System.DBNull)


    // No primary key values exist in the table.  This must mean that there are no records in

    // the table.  Therefore, we can safely assume this submit operation will create the first

    // primary key in the table.

    maxKey = 0;




    maxKey = (int)maxPrimaryKeyObject;


    Thanks again!


  15. Kayday says:

    Hi Forrest,

    Can you give me some guidance on how to do this for multiple tables that have parent-child relationship please??  Also, what if my table does not contain LastTimeStamp, how would I check if the data were changed?  Where should the modifications be? I’m not really good at C# …. 🙁

    Thanks a lot for any help.

  16. forrestd says:

    Hi Kayday,

    I don’t have a code sample to offer, so I’ll just throw out some ideas for logic you might follow to accommodate child tables.  There is a lot of room for personal preference when determining how tables should interact, but I’ll offer a very simple way.

    For the sample code I provided, I assume that you’ve setup your table with a surrogate primary key.  Now, assuming that you link your child table to your parent table, you would probably modify my merging code to do something like this (I’ll treat the specific case of 1 parent, 1 child):

    1.  Query the latest DataSet from the parent table.

    2.  Loop through the parent DataSet using the logic provided in the code sample to flag inserts/updates/deletes.

    3.  In the loop body, after you’ve flagged the change for the current record in the parent’s DataSet; query the child table, constraining the query to return only those records in the child table that match the parent record’s surrogate key.

    4.  Loop through the resultant child table recordset and diff the child DataSet rows against those queried from the DB (using the same logic provided in the original code sample.)

    So the pseudo-code would look something like this:

    Query Parent table

    Loop through parent table recordset to compare against submitted parent DataSet

      Mark the current parent record as insert/update/delete

      Query child table records that correspond to the current parent records surrogate primary key value.

      Loop through child table recordset to compare against submitted child DataSet

         Mark the current child record as insert/update/delete

      End loop

    End Loop

    That pseudo-code lends itself to recursing through multiple levels of a parent-child hierarchy.

    You’ll need to decide whether records in the child table should be deleted whenever the corresponding record in the parent table is deleted.  In other words, is the parent-child relationship a true foreign-key relationship, or is the relationship purely virtual, for the purpose of convenience?

    Hope that helps!

    Thanks, Forrest

  17. alex350r says:

    Great Post!

    Im having a problem though:

    Ive managed to configure the Web Service for my Database.

    When i create the infopath form i can only put the ‘data’ controls from the dbdataset into a ‘repeating’ section.

    The form i wish to design should just have one set of fields (non repeating) that submit to a database.

    How can i change this?

    Thanks, Alex

  18. mkoslof says:

    I’m sorry to cross post, and I mentioned this in another blog entry.  I am using SQL Server Native XML Web Services to act as a secondary datasource to InfoPath.  While this works great in the InfoPath rich client, it fails in InfoPath Forms Services and everything I have tried has led me no closer to a solution.

    I am puzzled by this and I’m not sure why this is a problem, is this not just SOAP and standard wsdl at play here.

    At this point, I am actually looking for a easy answer :).  Meaning, does anyone know if this is even possible through InfoPath Form Services?  Or is this a current limitation?  I have done tons with Web Services before and I’ve never had an issue like this.

    If the answer is, no, its not possible, are there any alternatives, besides writing my own web service to feed into InfoPath.  

    Please note at this point, just confirmation (either way, yes its possible, no its not supported) would be very helpful.  Thanks again


  19. Matt Faus says:

    Hey guys,

    This is a cool example!  Writing a web service to submit data to the SQL backend is a great idea, and that’s why we created our Database Accelerator product.  All you have to do is install it once, and then create a mapping from XML to SQL for each of the new form templates that you create.  This is a much better model than creating a new custom web service with every new form template.  We have used it on some very large projects, and it works great.

    Take a look here:

    If you have any questions, drop us a line in the Contact Us page! I hope this makes your developments easier!

    Matt Faus

    Qdabra Software

  20. Johnk says:

    Ok, I know how far behind I am and how new I am to development based on the age of the blogs I use to solve my issues.  

    I have set up MOSS 2007 Enterprise on Windows Server 2003 with SQL 2005 Advanced as the Database  for the whole shebang.  All is good.  I discovered Infopath and have written a form that works fine with the infopath client: on to submitting via web services through a browser enabled form ( no infopath client. ) In order to get the concept, I created a local database called test with your SQL scripts, populated a few rows and with Visual Studio 8 set up the web service, compiled it ( no changes ) and set off to design a test form.  

    I got to step 10 ( my url http://infincomd30/infopathwebservice/infopathwebservice.asmx?WSDL came up fine (I changed IPFSDiffGram to infopathwebservice throughout the webservice ) and gave me the 4 operation choices.  When I pick the DBData operation and click next, I get the 5 parameters tns:data1 – 5, but when I poulate them I get the following SOAP error "unable to create a schema …

    The SOAP response indicates that an error occurred on the server:

    System.Web.Services.Protocols.SoapException: Server was unable to process request. —> System.Data.SqlClient.SqlException: An error has occurred while establishing a connection to the server.  When connecting to SQL Server 2005, this failure may be caused by the fact that under the default settings SQL Server does not allow remote connections. (provider: Named Pipes Provider, error: 40 – Could not open a connection to SQL Server)

      at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection)

      at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj)

      at System.Data.SqlClient.TdsParser.Connect(ServerInfo serverInfo, SqlInternalConnectionTds connHandler, Boolean ignoreSniOpenTimeout, Int64 timerExpire, Boolean encrypt, Boolean trustServerCert, Boolean integratedSecurity, SqlConnection owningObject)

      at System.Data.SqlClient.SqlInternalConnectionTds.AttemptOneLogin(ServerInfo serverInfo, String newPassword, Boolean ignoreSniOpenTimeout, Int64 timerExpire, SqlConnection owningObject)

      at System.Data.SqlClient.SqlInternalConnectionTds.LoginNoFailover(String host, String newPassword, Boolean redirectedUserInstance, SqlConnection owningObject, SqlConnectionString connectionOptions, Int64 timerStart)

      at System.Data.SqlClient.SqlInternalConnectionTds.OpenLoginEnlist(SqlConnection owningObject, SqlConnectionString connectionOptions, String newPassword, Boolean redirectedUserInstance)

      at System.Data.SqlClient.SqlInternalConnectionTds..ctor(DbConnectionPoolIdentity identity, SqlConnectionString connectionOptions, Object providerInfo, String newPassword, SqlConnection owningObject, Boolean redirectedUserInstance)

      at System.Data.SqlClient.SqlConnectionFactory.CreateConnection(DbConnectionOptions options, Object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningConnection)

      at System.Data.ProviderBase.DbConnectionFactory.CreatePooledConnection(DbConnection owningConnection, DbConnectionPool pool, DbConnectionOptions options)

      at System.Data.ProviderBase.DbConnectionPool.CreateObject(DbConnection owningObject)

      at System.Data.ProviderBase.DbConnectionPool.UserCreateRequest(DbConnection owningObject)

      at System.Data.ProviderBase.DbConnectionPool.GetConnection(DbConnection owningObject)

      at System.Data.ProviderBase.DbConnectionFactory.GetConnection(DbConnection owningConnection)

      at System.Data.ProviderBase.DbConnectionClosed.OpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory)

      at System.Data.SqlClient.SqlConnection.Open()

      at infopathwebservice.GetDBData(Object[] queryParameters, SqlDbType[] parameterTypes)

      at infopathwebservice.DBData(String data1, String data2, String data3, String data4, String data5)

      — End of inner exception stack trace —

    My limited experience fails me on customizing the Instance Variables and the Webmethod query parameters ( which i did not do hoping that I was ok with supplied code just the test database ). I am familiar with connection strings etc.

    Could you please give me an example of declaring and/or using the Instance variables and Webmethod query parameters?  Thanks, John Koether

  21. Gandalf says:

    Hy, great exemple !!

    But I have a problem, i lauch my template InfoPath in my web browser (Internet Explorer) , the sumit data to my database SQL Server generata this message :

    "L’index se trouve en dehors des limites du tableau.

    System.IndexOutOfRangeException: L’index se trouve en dehors des limites du tableau.

    à Microsoft.Office.InfoPath.Server.SolutionLifetime.WebServiceHelper.HandleSubmitDataSetInput(XPathNavigator inputSubDOM, Boolean[] useDataSets, XmlDocument soapRequest, Solution solution, String name)

    à Microsoft.Office.InfoPath.Server.SolutionLifetime.WebServiceHelper.PrepareSoapRequest(XPathNavigator inputSubDOM, Boolean[] inputUseDataset, Solution solution, String name, Boolean useSelf)

    à Microsoft.Office.InfoPath.Server.SolutionLifetime.WebServiceHelper.ExecWebRequestSync(XPathNavigator inputSubDOM, Boolean[] inputUseDataset, XPathNavigator resultsSubDOM, Boolean resultUseDataset, XPathNavigator errorsSubDOM, Uri serviceUrl, Uri soapAction, Int64 timeOutMillisec, Solution solution, Document document, String name, Boolean isQuery, DataAdapterTimer dataAdapterTimer, DataAdapterCredentials credentials, Boolean useDcl, Boolean useProxy, Boolean useSelf)

    à Microsoft.Office.InfoPath.Server.SolutionLifetime.DataAdapterWebServiceSubmit.Execute(Document document, Uri soapAction, Uri serviceUrl, XPathNavigator querySubDOM, XPathNavigator resultsSubDOM, XPathNavigator errorsSubDOM, Int64 timeout, DataAdapterCredentials credentials, Boolean useDcl, Boolean useProxy, Boolean useSelf)

    à Microsoft.Office.InfoPath.Server.DocumentLifetime.DataAdapterWebServiceSubmit.ExecuteInternal(XPathNavigator queryFields, XPathNavigator resultFields, XPathNavigator errors)

    à Microsoft.Office.InfoPath.Server.DocumentLifetime.DataAdapterWebServiceSubmit.Execute()

    à Microsoft.Office.InfoPath.Server.SolutionLifetime.RuleAction.EvaluateExpression(Document document, XPathNavigator currentTarget)

    à Microsoft.Office.InfoPath.Server.SolutionLifetime.RulesRuleSet.<>c__DisplayClass7.<EvaluateExpression>b__4()

    à Microsoft.Office.InfoPath.Server.SolutionLifetime.RulesRuleSet.EvaluateExpression(Document document, XPathNavigator targetNavigator)

    à Microsoft.Office.InfoPath.Server.SolutionLifetime.ButtonFormCode.<>c__DisplayClass2.<Click>b__0()

    à Microsoft.Office.InfoPath.Server.SolutionLifetime.ButtonFormCode.Click(Document document, XPathNavigator container)

    à Microsoft.Office.InfoPath.Server.DocumentLifetime.EventClick.Play(Document document, BindingServices bindingServices, EventLogProcessor eventLogProcessor)

    à Microsoft.Office.InfoPath.Server.DocumentLifetime.Event.PlayEvent(Document document, BindingServices bindingServices, EventLogProcessor eventLogProcessor)

    à Microsoft.Office.InfoPath.Server.DocumentLifetime.EventLogProcessor.<>c__DisplayClass1.<ExecuteLog>b__0()

    à Microsoft.Office.InfoPath.Server.DocumentLifetime.EventLogProcessor.ExecuteLog(Int32 expectedEventLogID)

    à Microsoft.Office.InfoPath.Server.DocumentLifetime.Document.<>c__DisplayClass6.<PlayEventLog>b__3()

    à Microsoft.Office.Server.Diagnostics.FirstChanceHandler.ExceptionFilter(Boolean fRethrowException, TryBlock tryBlock, FilterBlock filter, CatchBlock catchBlock, FinallyBlock finallyBlock)"

    I hope you can help my…



  22. infopath says:

    Hi Gandalf,

    A question: are there currently any records in your SQL Server table? If not – for testing purposes please add a record to the table, test again and let us know if that worked or you still received the error.



  23. Gandalf says:

    Thanks Scott for your answer !

    Yes i have 3 record in my sql table.

    When i use the receive methode, the 3 records appears.

    I have drop en recreate my table, but i have always the errors message.

    (Just a another question, with this example, is it possible to write directly in my table ?)

    Have a nice day,


  24. infopath says:

    Hi Gandalf,

    Sorry for the delay…

    By chance, have you walked through creating this process using the *exact* steps/samples/files, etc. in this blog post? Do these steps work for you?

    In regard to your other question of writing directly to your table, I am not sure I understand the question.


  25. fencehead2 says:

    Hi Guys,

    Great example.

    I have followed through your instructions closely however when I reach step 6 InfoPath throws an error message "cannot use the web service because the method does not provide valid XML data". I am using the method UpdateDBData.

    I have made all the appropriate changes in the .cs file and if I build the solution in VS2005 it does run so I don’t think it’s an issue with the code. Also the database is created and the DML trigger is working.

    So everything seems to be in place for this example to work, just InfoPath seems to think it is not receiving valid XML.

    It would be cool if you could shed some light on this for me.



  26. Gandalf says:


    Infopath thanks for your anwser, but i have resolve this probleme.

    But, i have another probleme, in the exemple it is just nvarchar in table type. And in my utilisation i have float and int in table type.

    View my code with int :

    [WebMethod(Description = "Retrieve a DataSet containing timestamped data from a hard-coded database and table.", MessageName = "DBData-Static")]

       public DataSet DBData(string DESCRIPTION, Int32 CODE_CATEGORIE1, Int32 LIVRE1, Int32 PAPETERIE1, Int32 JEU1)


                                  // Create an array to contain the parameters.  These should include all the arguments for this WebMethod.

           object[] parameters = new object[] { DESCRIPTION, CODE_CATEGORIE1, LIVRE1, PAPETERIE1, JEU1 };

                                  // Create an array to indicate the SqlDbTypes of the columns for which the parameter values are specified.

                                  // parameterTypes[i] is the SqlDbType of the database column whose parameter value is specified by parameters[i]

           SqlDbType[] parameterTypes = new SqlDbType[] { SqlDbType.NVarChar, SqlDbType.Int, SqlDbType.Int, SqlDbType.Int, SqlDbType.Int };

                                  // Get the DataSet from the database.

                                  return GetDBData(parameters, parameterTypes);


    View my error message :

    La réponse SOAP indique une erreur :

    System.Web.Services.Protocols.SoapException: Le serveur n’a pas pu lire la demande. —> System.InvalidOperationException: Il existe une erreur dans le document XML (1, 445). —> System.FormatException: Le format de la chaîne d’entrée est incorrect.

      à System.Number.StringToNumber(String str, NumberStyles options, NumberBuffer& number, NumberFormatInfo info, Boolean parseDecimal)

      à System.Number.ParseInt32(String s, NumberStyles style, NumberFormatInfo info)

      à System.Xml.XmlConvert.ToInt32(String s)

      à Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReader1.Read3_DBDataStatic()

      à Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer4.Deserialize(XmlSerializationReader reader)

      à System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, String encodingStyle, XmlDeserializationEvents events)

      — Fin de la trace de la pile d’exception interne —

      à System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, String encodingStyle, XmlDeserializationEvents events)

      à System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, String encodingStyle)

      à System.Web.Services.Protocols.SoapServerProtocol.ReadParameters()

      — Fin de la trace de la pile d’exception interne —

      à System.Web.Services.Protocols.SoapServerProtocol.ReadParameters()

      à System.Web.Services.Protocols.WebServiceHandler.CoreProcessRequest()

    Je pense que c’est un problème de typage des données.

    Le matching entre le type base de données et type .NET doit pas être correct.

    I have see in this page the type .net to Sqldbtype

    I think it is a error in my type, are you any idea please ?

    Have a nice day,


  27. Rick315 says:


    I’ve tried this and I get to the point where I try to open the form in the InfoPath rich client.  I get the following error when trying to do so:

    The SOAP response indicates that an error occurred on the server:

    System.Web.Services.Protocols.SoapException: Server was unable to process request. —> System.IndexOutOfRangeException: There is no row at position 0.

      at System.Data.RBTree`1.GetNodeByIndex(Int32 userIndex)

      at System.Data.RBTree`1.get_Item(Int32 index)

      at System.Data.DataRowCollection.get_Item(Int32 index)

      at DiffgramService.MergeAndUpdateDBData(DataSet updatedDBDataSet, Object[] queryParameters, SqlDbType[] parameterTypes) in c:InetpubwwwrootIPFSDiffGramRickApp_CodeDiffgramService.cs:line 788

      at DiffgramService.UpdateDBData(DataSet updatedDBDataSet, String data1, String data2, String data3, String data4, String data5) in c:InetpubwwwrootIPFSDiffGramRickApp_CodeDiffgramService.cs:line 756

      — End of inner exception stack trace —




  28. infopath says:

    Hi Rick,

    Please accept our apologies as there is a slight error in the web service code. If you look in the "MergeAndUpdateDBData" function, you will see this line of code:

    DateTime timeStampFromTimeTable = (DateTime)updatedDBDataSet.Tables[TimeTable].Rows[0][QueryTimeColumn];

    When there are now rows in this table, this will generate the error you referenced. You need to comment that line of code and replace it with the following:

    DateTime timeStampFromTimeTable = Convert.ToDateTime("1/1/1900 12:00:00 AM");

    if (updatedDBDataSet.Tables[TimeTable].Rows.Count > 0)


               timeStampFromTimeTable = (DateTime)updatedDBDataSet.Tables[TimeTable].Rows[0][QueryTimeColumn];



  29. patrick1628 says:

    Hi Guys,

    I am a newbie doing this. How do I customize the web service for my database? Which form do I go to? What do I put?

    Please help.. or if you have any tutorials, please help!


  30. patrick1628 says:

    Hi Pls Help.

    I got " Could not open web service" error when trying to configure infopath form.

    it says not enugh space is available to process the command.

  31. scottd says:

    Is this still valid today? There seems to be conflicting information from MS regarding the use of SOAP and XML web services to access SQL databases. i.e. Native SOAP web services being deprecated in SQL Server 2008 R2. In addition, I don't see the ASP.NET Web Service template in VS 2010 Ultimate. I want to submit InfoPath web form data in SharePoint 2010 to a separate SQL database for analytics. Is this the recommmended approach in August of 2010?

  32. Raydir says:

    Hi Forrest

    I got a question concerning Infopath2010…

    Is there a way to write to SQL using Infopath WITHOUT a Sharepoint…?

    I used Infopath 2003 for sending todo-list from our project managers to one of our dev teams and this did work pretty fine.

    Now I was asked to connect to a SQL DB 2005 and i'm not sure if this is possible without a Sharepoint…


  33. James says:

    It seems like a TON of blogs from InfoPath 2003 and 2007 were copied into the InfoPath 2010 – but are they still relevant?

  34. gunjan says:

    Website Helpline, Website Support +91-8010010000

    Website Helpline India is a total website support company, Offer website support services under an annual contract at extremely affordable rates, We offers end-to-end website solutions which includes Domain Registration, Website Hosting, Website Design, Website Maintenance.


    Website Helpline, Website Support, Website Maintenance, Website Helpline Solution, Website Helpline Service, Website Redesign Helpline, Website Supports, Website Help Support, Website Design Company, Web Based Applications, SEO Support India, Website Redesign

    Contact US:->

    Website Support

    Call Now- +91-8010010000

  35. Simon Redding says:

    Is there an update of this article that covers Infopath 2010, VS 2010 / 2012 and SQLServer 2008/2012?



  36. Manishrao patil says:

    thanks for the post. Its good pointer.

Comments are closed.

Skip to main content