A Practical Guide to SharePoint 2013

A Practical Guide to SharePoint 2013
A Practical Guide to SharePoint 2013 - Book by Saifullah Shafiq

Monday, November 17, 2008

InfoPathMVP Award Program Blog

The following blog shares some of the inspiring activities of MVPs around the globe:

Wednesday, November 12, 2008

InfoPath Error: Cannot cast 'DataConnections[]' (which has an actual type of .....

Error:
(FileSubmitConnection)DataConnections["Submit"]              Cannot cast 'DataConnections["Submit"]' (which has an actual type of 'Microsoft.Office.InfoPath.Server.DocumentLifetime.SubmitToHostConnectionHost') to 'Microsoft.Office.InfoPath.FileSubmitConnection'            Microsoft.Office.InfoPath.FileSubmitConnection
Have you seen this error before? It occurs if you try to submit form to a host but you use data connection of type "FileSubmitConnection". Here is the code:
FileSubmitConnection  connection = (FileSubmitConnection) (DataConnections[“Submit”]);
You can submit to the following locations:
1. Web service
2. Forms library
3. As an email message
4. To the hosting environment
The code above is meant for submitting to a forms library. In workflow forms, people submit task forms to a hosting environment and they forget to change the data connection type, that is when they get this error. It is important you use correct casting when submitting the form. To submit a form (task form) to hosting environment, you should use following code:
SubmitToHostConnection  connection = (SubmitToHostConnection) (DataConnections[“Submit”]);

Sunday, November 9, 2008

Preserve code blocks are not supported in browser-enabled InfoPath forms

Preserve code blocks are not supported in browser-enabled InfoPath forms

The text on the button can be changed dynamically in InfoPath 2007. If you bind the button to a data source and then change the value of the data source using rules, the value of the button text will change dynamically. Can this be done programmatically? Yes! You can modify the XSL of the view to control the text of the button but the problem is this has to be done manually and when you load the view in editor, all your changes are lost. To preserve your changes, you must use "xd:preserve" but the problem is "xd:preserve" or "Preserve Code Block" is not supported in browser-enabled InfoPath forms. It will work in InfoPath client though. If you have no clue what I am talking about, then read the following article:

Using Custom XSLT in InfoPath Form Templates

This question is usually asked in forums where people ask if they can change the button text/label programmatically. As I mentioned above, the answer is "Yes" but it will be very difficult to manage the XSL if you cannot preserve your changes. Every time you want to publish your form, you will have to re-do your changes in the XSL. The following MSDN article clearly mentions that "xd:preserve" blocks are not supported in Forms services:

Creating InfoPath Form Templates That Work With Forms Services

After changing the XSL, you will see a red box on your form in the design mode with text "Preserve Code Block".



If you have enabled browser compatibility in your form, then the design checker will show the error:



"Preserve code blocks (xd:preserve) are not supported".

Click the error message, javascript pop-up will appear:



If you still want to go ahead and make changes in your XSL, remove the template block and save the changes outside InfoPath. Publish the form and your changes will work fine. In next article, I will show you how you can control the button text dynamically. It should have been other way round. I should have written about controlling button text first but anyway, doesn't make any difference.

Thursday, November 6, 2008

Wednesday, November 5, 2008

New Ajax book

New Ajax book is available November 12: Developing Service-Oriented AJAX Applications on the Microsoftr Platform

MS patterns and practices releases SharePoint Guidance

Codeplex site: www.codeplex.com/spg
This guidance helps architects and developers design, build, test, deploy and upgrade SharePoint intranet applications.

SharePoint for developers Track on MyRampUp.com

Ramp Up program has launched SharePoint for developers track today. 
Ramp Up is a free, online, community-based program that can help users save time in learning Microsoft technology. The easy-to-access content (provided by subject-matter gurus) is specifically tailored to the Ramp Up program, and offered in a variety of forms (whitepaper, v-lab, codecast and slidecast). This SharePoint track, along with the other currently offered tracks (eg, Visual Studio 2008), teaches the important skills in a guided path, making the learning process easier and more efficient. Currently, there are no assessments in the program, so it's quicker than ever to graduate and receive the reward (25% off on certification and 50% off on e-Learning - only for graduates of Ramp Up).

Wednesday, October 29, 2008

InfoPath Tip: Showing filtered column from a SharePoint list

Level: Beginners
Scenario: You have a list in SharePoint that contains user data (profile including name, phone, etc). You have an InfoPath form that has a text box to enter a user ID and a button to show record against the User ID entered in the text box.
Being a developer, a programmatic solution is very easy for me. With a few lines of code I can extract filtered data from a SharePoint list. What about those who are not SharePoint programmers! This tip will give you an easy solution.
1.       Add a new data connection in your form.
Step by Step
1.       Click "Manage Data Connections" in "Design Tasks". This will open a "Data Connections" box.
2.       Click the "Add" button.
3.       Select "Create a new connection to" option and then select "Receive data" option. Click "Next".
 
    
4.       Select "SharePoint library or list" and click "Next".
5.       Enter the URL of the list that will be used to fetch data from. Click "Next".
6.       Select list from the available lists and libraries and click "Next".
7.       Select the fields that you want to show in the form and click "Next". If you intend to use the form in Offline mode (that is when you are not connected to the SharePoint), then select the option "Store a copy of the data in the form template" otherwise do nothing and click "Next".
8.       Enter a name for this new data connection and select "Automatically retrieve data when form is opened" and click "Finish".
9.       Click "Close".
 
2.       Display data in your form. Suppose you want to show a single field/column in your form. Follow the instructions below to show a single field.
 
1.       Add a data source (type: string).
2.       Right click the new data source and select "Properties".
3.       "Data" tab is selected by default when your open the control's properties. Click the function button (fx) that is located on the right side of the "Value" field.
 
    
4.       Click "Insert Field or Group." button.
5.       Select the data connection that you created in the first step from the "Data Source" drop down.
6.       Expand nodes unless you can see all field/column names. Select the column name that you want to show in your form. As I said earlier, we are assuming that we are retrieving user profile data from a SharePoint list and this data will be filtered by a value passed from the InfoPath form. As I mentioned in the scenario above, there is a field that will contain a User ID entered by the user. So after you select the value that you want to show on your form, click the "Filter Data." button. This button remains disabled unless you select a field.
7.       Click "Add" button.
8.       There will be three drop down boxes on the form. The first drop down will have the column names retrieved from the SharePoint list and by default the column name you selected in the previous step will be selected in the drop down. The second drop down contains the filter conditions. Keep the default condition selected, that is, "is equal to". In the third drop down, Select "Type text ." if you want to hard code the user ID against which you want to show the data. If you want to keep it dynamic then select "Select a field or group.".
9.       From the "Data Source" drop down, select the main data source and then select the field name that corresponds to the "User ID" text box on your form. Click "Ok" and then again click "Ok". Click "Ok" thrice more to close open boxes and then click "Ok" once more to close the main properties box.
10.   Drag and drop the data source to your form. Save the form and run it to view the preview. (Hint: If this is a web enabled form, make sure to set the postback settings of the control that will show data to "Always".)
 
Repeat the steps above for each new field added to your form to show the SharePoint list column data.
  

Friday, September 19, 2008

Populating InfoPath drop down with "FILTERED" SharePoint list data programmatically

This article shows how one can populate InfoPath drop downs with "FILTERED" SharePoint list data. This article uses SPQuery to query the SharePoint lists.

Thursday, August 28, 2008

Comparing two different date formats

If one date control is using a format different than the other date control, how will you compare the dates? Why will this happen? Why will the two dates be using different formats in the same form? well, you can't argue with the client. can you? This was a real scenario that I faced some time ago. So, convert the dates to one format and compare them. For example,
   string shortDate1 = Microsoft.VisualBasic.Strings.FormatDateTime(Convert.ToDateTime(Date1), Microsoft.VisualBasic.DateFormat.ShortDate);
   string shortDate2 = Microsoft.VisualBasic.Strings.FormatDateTime(Convert.ToDateTime(Date2), Microsoft.VisualBasic.DateFormat.ShortDate);
   if (DateTime.Parse(shortDate1) < DateTime.Parse(shortDate2))
   {
         //Display message
   }
In the code above, I am comparing two dates, Date1 and Date2. These dates are stored in string format in the form. So we convert them to date format first and then to short date format and then compare them.

Monday, August 18, 2008

InfoPath: Deleting all rows except the first one in repeating table

Code:
XPathNavigator Node = this.CreateNavigator().SelectSingleNode("/my:myFields/my:RepeatingGroup", this.NamespaceManager);
XPathNodeIterator node_2b_deleted = this.CreateNavigator().Select("/my:myFields/my:RepeatingGroup", NamespaceManager);
                                    if (node_2b_deleted.Count > 1)
                                    {
                                        string group = "/my:myFields/my:RepeatingGroup";
                                        XPathNavigator firstItem = Node.SelectSingleNode(groupResults + "[2]", NamespaceManager);
                                        XPathNavigator lastItem = Node.SelectSingleNode(groupResults + "[position()=last()]", NamespaceManager);
                                        firstItem.DeleteRange(lastItem);
                                        lastItem = null;
                                        firstItem = null;
                                    }
                                    node_2b_deleted = null;
Explanation:

We start with second row and delete all rows till the last row. Why will we leave the first row? It depends. There are scenarios where one required to re-populate the repeating table after deleting all rows. In that case, if there is no first row, it will not be possible to create a clone of the first row. We first create a clone of the first row and then populate the fields of the repeating row. This continues until all rows are populated with data and then we delete the master row to avoid creating a duplicate entry of the first row. So, first row is always required. You can blank out all fields in the first row and if the repeating table is in a section, hide the section which will give users the feeling that whole repeating table has been deleted.

Saturday, August 16, 2008

Populating InfoPath drop down with SharePoint list data programmatically - Part 2 (Using SPQuery)

Learn how to use SPQuery object to fetch data from a SharePoint list.  SPuery is fast and efficient. Populate InfoPath drop down with SharePoint list data.

Saturday, July 12, 2008

Populating InfoPath drop down with SharePoint list data programmatically

Learn how to use SPQuery object to fetch data from a SharePoint list.  In one of the previous articles, you saw how one can populate a drop down list box without writing code but now you will see how to do it programmatically. Programming means more power in your hands!

Wednesday, July 9, 2008

InfoPath: Raising an error on validation

InfoPath provides excellent method to validate controls, for example, you can use data validation alone or in conjuction with Rules to validate data in InfoPath forms. You can also do it  programmatically and raise errors which will be shown in the form when there is a validation error. Assume there is a control called FirstName. Here is how you will raise an error on FirstName:
public void FirstName_Changed(object sender, XmlEventArgs e)
{

}
Right click the control and select Programming > Changed Event. Note, Validating Event is also available but we will use Changed Event. Raise any previously raised errors:
this.Errors.Delete("FirstNameError");
After validating, if there is an error, raise it:
 this.Errors.Add(Nav, "FirstNameError", "Please add correct value in First Name");
The first parameter is the XPathNavigator object that points to the control.
XPathNavigator nav = this.CreateNavigator().SelectSingleNode(XPath of the firstname field, this.NamespaceManager);
XPath will be like "/my:myFields/my:FirstName".
The second parameter is the name of the error and third parameter is the description of the error.
Happy programming!

Wednesday, June 18, 2008

Populating InfoPath Drop down with SharePoint List Data


Hard coding values in InfoPath drop down list box is easy but you can also populate it with dynamic data. Data can be from an XML file, a database or even a SharePoint list. This article shows how you can populate the list box with data from a SharePoint list with out writing a line of code.



Friday, June 6, 2008

InfoPath: Reading from a repeating table

I will start with the code first and then explain what's happening.
Code:
 XPathNavigator DOM = this.MainDataSource.CreateNavigator();
XPathNodeIterator nodes = DOM.Select("/my:myFields/my:RepeatingGroup", this.NamespaceManager);
              XPathNavigator nodesNavigator = nodes.Current;
              XPathNodeIterator nodesText = nodesNavigator.SelectDescendants(XPathNodeType.Element, false);
             string FirstName = "";
             string LastName = "";
              while (nodesText.MoveNext())
              {
                  if (nodesText.Current.Name == "my:FirstName")
                  {
                         FirstName = nodesText.Current.Value.ToString();
                  }
                  nodesText.MoveNext();
                 if (nodesText.Current.Name == "my:LastName")
                 {
                       LastName= nodesText.Current.Value.ToString();
                 }
        }
         
              nodesText = null;
              nodesNavigator = null;
              nodes = null;
             DOM = null;

Explanation:
It's a very commong scenario. Developers want to read from the repeating table programmatically. The above code just does that. You take the XPath for the repeating group and create a nodes iterator object. This will iterate through all the descendant nodes. If the node type (XPathNodeType) is "Element", the value will be read into a string variable. That's it. Use MoveNext() to move to the next node in the hierarchy. It's as simple as that!

Wednesday, May 14, 2008

XPath, XQuery, and XSLT Functions

Some XML functions can be very useful in InfoPath, especially if you are an InfoPath developer. For example, suppose you are using data validation in your InfoPath form and you want the users to enter a value in one of the text boxes on your form. Of course, you can use the built-in data validation functions, for example, "If field is blank then show error alert" but users can dodge you by entering a space in the text box. In this case, InfoPath won't generate any error and will accept the value entered by the user. How can handle this situation? The answer is XML functions. You can use normalize-space() function. Right click the control and select "Data Validation". In the drop down, select "The expression" and in the text box enter normalize-space(.)="". In the screen tip, enter "Please enter valid value" and click Ok. InfoPath will now show an error if users try to enter an invalid value like a whitespace. Similarly, you can use other XML functions in your code or to validate data using the built-in data validation. More functions can be found on the following page. The page has the list of functions and examples to show how each function works:
 
-SSA

Tuesday, May 6, 2008

How to grant permissions to a custom assembly that is referenced in a report in Reporting Services

It seems straight forward. Isn't it? but it may not be as simple and straight forward for the newbies as it seems at first. A colleague and a  friend of mine recently was struggling with the same issue and he learnt the lesson after spending considerable amount of time experimenting with different solutions. You get a security exception when you write your own component to be used in a report in reporting services. My friend is working on a SharePoint project that involves reporting services. He created a report that used a custom built component. The code used SharePoint object model. He tried to use Elevated privileges but even that didn't work because the error is thrown on the line that has the elevated priviliges code. He even tried the code access security, that didn't work. The following KB article has information about this problem:
 http://support.microsoft.com/kb/842419/ (How to grant permissions to a custom assembly that is referenced in a report in Reporting Services)
Use following code to get rid of the security exception:
SharePointPermission perm = new SharePointPermission(PermissionState.Unrestricted);
perm.Assert();
//Code using SharePoint object model here!!
perm.Deny();
Include following DLL in the references before you use the above code:
Microsoft.SharePoint.Security.DLL
This DLL will be found in the 12 hive. Exact location is as following:
System Drive:Program FilesCommon FilesMicrosoft SharedWeb Server Extensions12ISAPI
Add following namespaces at the top:
using Microsoft.SharePoint;
using Microsoft.SharePoint.Security;
using System.Security.Permissions;
That's it. Your component will now work fine.

Monday, May 5, 2008

Creating SharePoint List Views Programmatically

Learn how to create SharePoint list views programmatically.

Validating contact selector control programmatically

How to know if contact selector is empty?
XpathNavigator selector = this.CreateNavigator().SelectSingleNode("/my:myFields/my:contactselector", this.NamespaceManager);
if (selector.SelectChildren(XPathNodeType.Element).Count == 0)
{
this.Errors.Add(selector, "Error","Selector is empty");
}
How to raise error if user has selected more than one person in the selector?
if (selector.SelectChildren(XPathNodeType.Element).Count > 1)
{
this.Errors.Add(selector, "Error","Please select one user");
}
How to tell if user hasn't selected a valid person?
  selector = selector.SelectSingleNode("my:Person", this.NamespaceManager);
XPathNavigator displayname = this.CreateNavigator().SelectSingleNode("/my:myFields/my:contactselector/my:Person/my:DisplayName", this.NamespaceManager);
string strDisplayName = displayname.value.toString();
XPathNavigator accountid = this.CreateNavigator().SelectSingleNode("/my:myFields/my:contactselector/my:Person/my:AccountId", this.NamespaceManager);
string strAccountid = accountid.value.toString();
XPathNavigator accounttype = this.CreateNavigator().SelectSingleNode("/my:myFields/my:contactselector/my:Person/my:AccountType", this.NamespaceManager);
string strAccountType = accounttype.value.toString();

                    if (string.IsNullOrEmpty(strDisplayName)) ||
                        string.IsNullOrEmpty(strAccountId)) ||
                        string.IsNullOrEmpty(strAccountType))
                    {
                         this.Errors.Add(selector,"Error","Please select valid user");
                    }
Note: This was off the top of my head, you may find minor mistakes in XPaths or spellings.

Sunday, April 20, 2008

MVP Summit experience

Returned from the summit on friday night but my body was so sour that I spent whole saturday sleeping, relaxing, and watching TV. This was my first summit experience and undoubtedly it was the best experience I have had in recent times. This was the first time I met SharePoint MVPs in person. I have uploaded some pictures that I took during the summit, here are the URLs:
The sessions were very informative and I got chance to spend some quality time with the other MVPs during the events like Paintball, Attendee party, PG dinner, etc. I also got chance to meet with MVPs from around the world. All in all, it was an excellent experience and I really enjoyed the visit and I hope to visit the summit again next year which is expected to start on March 1st, 2009. Those of you interested in finding out how we SharePoint MVPs had fun at the summit may want to read the following blog post:

-Saif


Friday, April 18, 2008

Permissions error when adding data to a list (programmatically)

MSDN article does not mention this but the code smaple wont work if you copy it directly from the MSDN article. You get an error when you try to add a record in list. Here is the code:
SPSite site = SPContext.Current.Site;
SPWeb localweb = site.OpenWeb();
SPList list = localweb.Lists["User List"];
SPListItem listItem = list.Items.Add();
localweb.AllowUnsafeUpdates = true;
listItem["Title"] = "test";
listItem.Update();
localweb.AllowUnsafeUpdates = false;
This will not work. First thing, you should use elevated privileges to get rid of the permissions exception. Second thing, the SPContext should be used outside the elevated privilges code. Here is how to do it correctly:

SPWeb webroot = null;
try
{
webroot = SPContext.Current.Web;
SPSecurity.RunWithElevatedPrivileges(delegate()
{
using (SPSite site = new SPSite(webroot.Site.ID))
{
using (SPWeb localweb = site.OpenWeb(webroot.ID))
{
SPList list = localweb.Lists["User List"];
SPListItem listItem = list.Items.Add();
localweb.AllowUnsafeUpdates = true;
listItem["Title"] = fname.Value.ToString();
listItem.Update();
localweb.AllowUnsafeUpdates = false;
}
}
});
Instantiate the SPWeb object to null. Assign SPContext outside elevated privileges. Set AllowUnsafeUpdates to true before updating the item.

Thursday, April 10, 2008

Programming InfoPath Web Forms

InfoPath makes it easy to create electronic forms without coding. Programming InfoPath XML forms is fun. You can take full advantage of the new InfoPath forms services by creating solutions through coding. Programming gives you power and you can do several things that may not be possible without it. For example, creating a multi-select list box for browser enabled forms is one example. The out-of-the-box multi-select list box does not work in browser forms. You can create one using the out-of-the-box repeating table. This introductory level article does not cover those details but shows how you can create a programmatic solution using VSTA.

Tuesday, April 1, 2008

MVP Renewed!

My MVP award has been renewed for another year. I am very happy and very excited because I have lots of interesting plans this year. I would like to thank all my well wishers and readers who read my blog and articles and send positive feedback and comments. Thank you!

 -SSA

Saturday, March 22, 2008

External Collaboration Toolkit for SharePoint released

External Collaboration Toolkit for SharePoint has been released and can be downloaded from http://www.microsoft.com/collabkit. The toolkit runs on MOSS 2007 and WSS 3.0.

Friday, March 14, 2008

How to find a node using expressions

If your main data source contains hundreds of nodes, how will you find one using expressions? Suppose "Nodes" is the parent node with the following xpath:
XPathNavigator nodes = this.CreateNavigator().SelectSingleNode("/my:myFields/my:Nodes", this.NamespaceManager);
To find nodes inside "Nodes" (parent node), do the following
nodes.SelectSingleNode("child::*[contains(name(),"abc")]");
This will select the child node that has "abc" in its name. This is just an example and can have many practical uses.

Publishing web enabled InfoPath form using STSADM command

Learn how to publish web enabled InfoPath forms using STSADM command line utility. It's simple. Admins use stsadm to publish forms. It's easy to create a batch file of commands that will remove form, deactivate form, upload form, activate form and upgrade form when needed.

Tuesday, February 5, 2008

SharePoint Capacity Planner Tool is now available for download

You can read about the SharePoint Capacity Planner Tool on the following page:
You can download the tool from the same page or download it directly from the following page:
You can download the System Center Capacity Planner 2007 from the following link:
The direct link to download the System Center Capacity Planner 2007 is as follows:

-SSA

Sunday, February 3, 2008

Validating contact selector control programmatically

How to know if contact selector is empty?

XpathNavigator selector = this.CreateNavigator().SelectSingleNode("/my:myFields/my:contactselector", this.NamespaceManager);
if (selector.SelectChildren(XPathNodeType.Element).Count == 0)
{
this.Errors.Add(selector, "Error","Selector is empty");
}
How to raise error if user has selected more than one person in the selector?
if (selector.SelectChildren(XPathNodeType.Element).Count > 1)
{
this.Errors.Add(selector, "Error","Please select one user");
}
How to tell if user hasn't selected a valid person?
  selector = selector.SelectSingleNode("my:Person", this.NamespaceManager);
XPathNavigator displayname = this.CreateNavigator().SelectSingleNode("/my:myFields/my:contactselector/my:Person/my:DisplayName", this.NamespaceManager);
string strDisplayName = displayname.value.toString();
XPathNavigator accountid = this.CreateNavigator().SelectSingleNode("/my:myFields/my:contactselector/my:Person/my:AccountId", this.NamespaceManager);
string strAccountid = accountid.value.toString();
XPathNavigator accounttype = this.CreateNavigator().SelectSingleNode("/my:myFields/my:contactselector/my:Person/my:AccountType", this.NamespaceManager);
string strAccountType = accounttype.value.toString();

                    if (string.IsNullOrEmpty(strDisplayName)) ||
                        string.IsNullOrEmpty(strAccountId)) ||
                        string.IsNullOrEmpty(strAccountType))
                    {
                         this.Errors.Add(selector,"Error","Please select valid user");
                    }

Note: This was off the top of my head, you may find minor mistakes in XPaths or spellings.

InfoPath: Copying content of one section to another

If you have two sections (sections can have anything including file controls) and you want to copy content from one section to another, here is how you do it:
string sourceXPath = "/my:myFields/my:Source";
string destXPath = "/my:myFields/my:Destination";
 XPathNavigator source = this.CreateNavigator().SelectSingleNode(srcXPath, this.NamespaceManager);
            XPathNavigator dest = this.CreateNavigator().SelectSingleNode(destXPath, this.NamespaceManager);
            if (dest.MoveToAttribute("nil", "http://www.w3.org/2001/XMLSchema-instance"))
                dest.DeleteSelf();
            if (source.InnerXml.Contains("xsi:nil="))
            {
                //Do nothing
            }
            else
            {
                if (dest.InnerXml.Contains("xsi:nil="))
                {
                    dest.InnerXml = source.InnerXml;
                }
                else
                {
                    dest.InnerXml += source.InnerXml;
                }



Sunday, January 27, 2008

Office SharePoint Designer 2007 Step by Step, is now in the book shops pre

Microsoft Office SharePoint Designer 2007 Step by Step is now available in the market. The book targets the Information workers. Introduction of the book can be read on the author's (Penny Coventry) blog:
Microsoft site also has some details on the book:
I will post a review of this book as soon as i get a copy.

-SSA

Sunday, January 20, 2008

Links for Workflow with VS 2008

People have already started blogging about the workflow creation with VS 2008. Here are a couple of cool links that show how to create sequential workflows using VS 2008:
Webcast:
Also, do read the following good article about VS 2008 written by Dino Esposito:

-SSA

Tuesday, January 15, 2008

InfoPath Error: The given key was not present in the dictionary.

If this error occurs when you try to submit the form, then there can be two reasons for this. The data connection name is not correct or the URL used in the data connection is not correct. Sometimes, it is hard to pin point the problem because the URL will not be accepted if it has a problem, no matter how minor. An extra space, an illegal character, etc are the problems that are hard to locate and are the source of this error. This usually occurs when you try to submit the form programmatically because directly publishing the form to the SharePoint allows you to select the site and library so there is no chance of entering a malformed URL but when you submit the form programmatically using a data connection, you have to provide the URL manually. The details of the error are as follows:
------------------
 The given key was not present in the dictionary Source: Microsoft.Office.InfoPath.Server Stack trace:   at Microsoft.Office.InfoPath.Server.DocumentLifetime.OMExceptionManager.ExecuteOMCallWithExceptions(OMCall d, ExceptionFilter exceptionFilter)
   at Microsoft.Office.InfoPath.Server.DocumentLifetime.OMSecurityContext.ExecuteOMCall(Solution solution, SecurityLevel methodSecurityLevel, ExceptionFilter exceptionFilter, OMCall d)
   at Microsoft.Office.InfoPath.Server.DocumentLifetime.OMSecurityContext.ExecuteOMCall(Solution solution, SecurityLevel methodSecurityLevel, OMCall d)
   at Microsoft.Office.InfoPath.Server.DocumentLifetime.DataConnectionCollectionHost.get_Item(String name)
   at function() in Pathcode.cs:line 394
   at function() in Pathcode.cs:line 290Location:Void ExecuteOMCallWithExceptions(Microsoft.Office.InfoPath.Server.DocumentLifetime.OMCall, Microsoft.Office.InfoPath.Server.DocumentLifetime.ExceptionFilter)
For more information, see Help and Support Center at http://go.microsoft.com/fwlink/events.asp.
---------------------------
Code to submit form programmatically:
 public void FormEvents_Loading(object sender, LoadingEventArgs e)
 {
       string srcLoc = e.InputParameters["Source"].ToString();
       srcLoc = srcLoc.Substring(0, srcLoc.IndexOf("/", 8));
       libLoc = srcLoc + e.InputParameters["XmlLocation"].ToString();
 }
FileSubmitConnection SubmitConnection = (FileSubmitConnection)this.DataConnections["Mainsubmit"];
SubmitConnection.FolderUrl = libLoc.Substring(0, libLoc.LastIndexOf("/"));
SubmitConnection.Execute();
"Mainsubmit" is the data connection name. If there is a spelling mistake in this name, you will get the error. If there is a spelling mistake in the URL used in this connection, again there will be an error. You need to be extra careful when publishing the form. It is hard to notice the problem because the form publishes OK with out any problems and you only get the error when you run the form from SharePoint.

InfoPath: Delete file attachments programmatically (C#)

There is a section in your form that file attachment control or you can have attachment controls in a repeating table to allow multiple attachments and if you want to delete the file attachments using C#, here is the solution:
   XPathNavigator files = this.CreateNavigator().SelectSingleNode("/my:myFields/my:RepeatingGroup/my:FileAttachments", this.NamespaceManager);
                    XPathNodeIterator Node_2b_Deleted = this.CreateNavigator().Select("/my:myFields/my:RepeatingGroup/my:FileAttachments", NamespaceManager);
                    string attachments = "/my:myFields/my:RepeatingGroup/my:FileAttachments";
                    XPathNavigator firstItem;
                    XPathNavigator lastItem;
                    if (Node_2b_Deleted.Count > 1)
                    {
                        firstItem = files.SelectSingleNode(attachments + "[1]", NamespaceManager);
                        lastItem = files.SelectSingleNode(attachments + "[position()=last()]", NamespaceManager);
                        firstItem.DeleteRange(lastItem);
                        lastItem = null;
                        firstItem = null;
                    }
                    else if (Node_2b_Deleted.Count == 1)
                    {
                        firstItem = files.SelectSingleNode(attachments + "[1]", NamespaceManager);
                        firstItem.DeleteSelf();
                    }

                    Node_2b_Deleted = null;
                }
You define the XPath that points to the file attachments. You take the first node (attachments[1]) and the last node (attachments[position=last()] and delete the attachments:
firstItem.DeleteRange(lastItem); where first item points to the first node and lastItem points to the last node. If there are more than 1 attachment, then DeleteRange() is used but if there is only attachment, then you can use DeleteSelf() to remove the only node.
That's it. Confusion? Contact me!

Wednesday, January 2, 2008

Sorting repeating table


I have already given a programmatic solution of sorting a repeating table in InfoPath but here is another way of doing it: