Tuesday 7 July 2009

How to create Class from InfoPath Schema

  1. On the File menu, click Save As Source Files and save the form files in a folder on your local computer. There will be a file called myschema.xsd among the files you just saved.
  2. Close InfoPath.
  3. Open a Visual Studio 2005 Command Prompt which you can access via Start > Programs > Microsoft Visual Studio 2005 > Visual Studio Tools.
  4. At the command-line prompt, use the cd command to navigate to the folder where you saved the form files. To generate a C# class for the form, at the command-line prompt type:
    1. xsd myschema.xsd /c /l:cs
  5. This will create a C# file named myschema.cs for the InfoPath form.

Note: Once you have created the class and examine it, you will notice that the name of the class is the same as the name of the root node of the InfoPath form. So if you want the generated class to have a meaningful name other than myFields, which is the default name assigned to the root node of an InfoPath form, you must change the name of the root node in InfoPath to the name you want the generated class to have, before you create the .NET class.

How to make a Folder accessible in SharePoint

If you want to show files from a folder within SharePoint, you can use the PageViewer Webpart.

This can be usefull if you want to make your logfiles accessible without having to log on to the server.

Therefore just

  1. add a PageViewer WebPart to your Webpart Page.
  2. Set the WebPart Properties to show Files from a Folder.
  3. Enter the link to the folder e.g. \\servername\LogFiles

Use Audience Targeting to adapt the visibility of the Webpart.

How to Access SharePoint User Information in InfoPath

In InfoPath 2007 you can get the logon name of the current user by using the built-in function username(). (http://blogs.msdn.com/infopath/archive/2006/05/26/608092.aspx)

If you want to get more information that just the user name you should use the UserprofileService Web Service of MOSS. You have two options with this service:

  1. You can pass the account information of the user who’s details you need
  2. You can pass a null value, which will cause the web service to grab the current users identify

How to do it:

Step 1: Create the form

  1. Open InfoPath and design a new, blank form
  2. Save the form

Step 2: Set the security level of the form

  1. From the Main Toolbar, select Tools | Form Options
  2. Select Security and Trust from the list box
  3. Clear the checkbox next to Automatically determine security level
  4. Select Full Trust
  5. Hit OK.

Step 3: Add code to the form

  1. From the Main Toolbar, select Tools | Programming | Loading Event
  2. Right-click on UserProfileDemo node of the Project Explorer and choose Add Web Reference
  3. Enter the following for the URL: http://<yourServerName>/_vti_bin/UserProfileService.asmx
  4. Enter the following for Web reference name: ProfileService
  5. Click Add Reference
  6. Replace the FormEvents_Loading event handler with the following code snippet:

ProfileService.UserProfileService profileService = new Gravity.IP.Activities.SignUp.ProfileService.UserProfileService();
profileService.UseDefaultCredentials = true;
ProfileService.PropertyData[] userProps = null;
// Passing null to this method causes the profile of the current user to be returned.
userProps = profileService.GetUserProfileByName(null);
int prefferedNamePropID = -1;
if((userProps != null) && (userProps.Length != 0)){
    for (int i = 0; i < userProps.Length; i++) {
        if(prefferedNamePropID != -1){
            switch (userProps[i].Name.ToLower())  {
                case "preferredname":
                    prefferedNamePropID = i;
                    break;
            }
        }else{
            break;
        }
    }
}
if (prefferedNamePropID != -1) {
    ProfileService.ValueData[] values = userProps[prefferedNamePropID].Values;
    if (values.Length > 0) {
        String currentUserDisplayName = values[0].Value.ToString();
    }
}

Monday 6 July 2009

Hot to get Item ID in InfoPath Instantiation Form

When using an InfoPath Form as an Instantiation Form for a Workflow, the Form is loaded inside a XmlFormView WebPart.

Due to this you cannot get Query Parameters via the InputParameters (http://msdn.microsoft.com/en-us/library/microsoft.office.infopath.loadingeventargs.inputparameters.aspx).

Instead you should add a reference to System.Web and use HttpCurrent.Context.Request.QueryString to fetch the values.

String id = HttpContext.Current.Request.QueryString("ID")

How to use InfoPath for a Workflow Instantiation / Association Form

Possible Forms:

  • Association form - this pops up when a WF is associated with a list.
  • Initiation form - this pops up when a WF is initiated on a list item.
  • Modification form - you'd use this WF to perform a modification on the WF.
  • Task form - this can be used to substitute for the task created for the WF.

Important: The schema of the init and association form must be the same. If you want to have different Form, you should make both forms in one and hide the fields depending on the type of call.

This How To uses the example of a list selection when the workflow is initiated.

1. Create the Form

Open InfoPath and create a new blank form template. Select 'Enable browser-compatible features only'.

2. Get the Workflow Context

(http://msdn.microsoft.com/en-us/library/ms558892.aspx)

Create a XML File with the following content

<Context isStartWorkflow="true"isRunAtServer="false"provideAllFields="true"siteUrl=""/>



Following are the elements of the schema:




  • Context   Root element that represents the workflow context information being passed to the form. The Context element has the following attributes:


  • isStartWorkflow   Boolean; true if the form is being used as the workflow initiation form. You can use a specified form as both workflow association and initiation form, and it can present different views at each stage.


  • isRunAtServer    Boolean; true if the form is being opened on the server.


  • provideAllFields    Boolean; true if the form is being used as the last point of user interaction before the workflow starts. This means the form is being used either as a workflow initiation form or as a workflow association form for a workflow you have specified to start automatically.


  • siteUrl   String. The URL of the SharePoint site from which the form is being opened.


Note:  The form does not use the actual values specified in the first three attributes; they are included solely to indicate that the attributes are defined as Boolean data types.



Save the file to your computer Add the context schema to your Form





  • In Office InfoPath 2007, on the Design Tasks pane, select Data Source, and then click Manage Data Connection.


  • In the Data Connections dialog box, click Add.


  • In the Data Connection Wizard, select Create a new connection to, and then select Receive data. Click Next.


  • Select XML Document, and then click Next.


  • Browse to the location where you saved your Context.xml file, select it, click Open, and then click Next.


  • Select Include the data as a resource file in the form template, and then click Next.


  • Type Context as the data connection name, and ensure that Automatically retrieve data when form is opened is selected. Click Finish, and then click Close.




After you include the Context.xml file as a resource file in the form template, you no longer need the file. You do not need to include the file in your workflow solution.




3. Design the Form



Main Data Source



Add a RepeatingTable Control (Lists – List – ListName, ListID)



Note: This control is just added for the creation of the Data Source Fields, it can be removed from the directly





Add a DropDown Control (SelectedList)




Set the Control Properties to look up the values in the Repeating Table Fields




using Microsoft.Office.InfoPath; 


Lists DropDown Properties 



Add the Code




Click On Tools –> Programming –> Loading Event to open Microsoft Visual Studio Tools for Applications






Note: to install Microsoft Visual Studio Tools for Applications you have to go to Control Panel –> Add or Remove Programs –> Select your Office installation –> Change –> Add or Remove Features; You have to enable it for every Office Application with which you want to use it.




a) Include a Reference to Windows SharePoint Services to you project




b) use the following using statements



using Microsoft.Office.InfoPath; 
using System;
using System.Xml;
using System.Xml.XPath;
using Microsoft.SharePoint;
using System.Collections.Generic;



c) Create Properties




Note: Member variables are not supported in browser-enabled forms. Instead, write and read these values from the FormState dictionary




private String SiteUrl { 
get {
if (FormState["SiteUrl"] != null) {
return FormState["SiteUrl"].ToString();
} else {
return String.Empty;
}
}
set {
FormState["SiteUrl"] = value;
}
}
private String SelectedListID {
get {
if (FormState["SelectedListID"] != null) {
return FormState["SelectedListID"].ToString();
} else {
return String.Empty;
}
}
set {
FormState["SelectedListID"] = value;
}
}




 d) add a method for removing the initial empty entry in the DropDown





private void emptyListDropDown() { 
XPathNavigator myRoot = MainDataSource.CreateNavigator();
XPathNavigator xnContentTypes = myRoot.SelectSingleNode("/my:ListSelector/my:Lists", NamespaceManager);
List<XPathNavigator> nodesToDelete = new List<XPathNavigator>();
foreach (XPathNavigator option in xnContentTypes.Select("..//my:List", NamespaceManager)) {
nodesToDelete.Add(option);
}
//delete all nodes on the list
foreach (XPathNavigator option in nodesToDelete) {
option.DeleteSelf();
}
}




e) add a method for getting the Context Information





private void getContextData() { 




XPathNavigator secDSNav = DataSources["Context"].CreateNavigator();




if (secDSNav.MoveToChild(XPathNodeType.All)) {

string myNamespace = NamespaceManager.LookupNamespace("");




SiteUrl = secDSNav.GetAttribute("siteUrl", myNamespace);

}


}




f) add methods for loading the Lists from SharePoint and add them to the DropDown Control





//fills the list dropdown with all non hidden lists from the site 

private void loadSharePointLists(String siteUrl) {


using (SPWeb oWeb = new SPSite(siteUrl).OpenWeb()) {


foreach(SPList oList in oWeb.Lists){


if(!oList.Hidden){


createAndAddDropDownListItem(oList.Title, oList.ID.ToString());


}


}


}


}




private void createAndAddDropDownListItem(String name, String guid) {

string myNamespace = NamespaceManager.LookupNamespace("my");


XPathNavigator myRoot = MainDataSource.CreateNavigator();


XPathNavigator node = myRoot.SelectSingleNode("/my:ListSelector/my:Lists", NamespaceManager);


DeleteNil(node);


using (XmlWriter writer = node.AppendChild()) {


writer.WriteStartElement("List", myNamespace);


writer.WriteElementString("ListName", myNamespace, name);


writer.WriteElementString("ListID", myNamespace, guid);


writer.WriteEndElement();


writer.Close();


}


}




public void DeleteNil(XPathNavigator node) {

if (node.MoveToAttribute("nil", "http://www.w3.org/2001/XMLSchema-instance")) {


node.DeleteSelf();


}


}




g) adapt the Loading Method to load the DropDown Control





public void FormEvents_Loading(object sender, LoadingEventArgs e) { 

emptyListDropDown();


getContextData();


String siteUrl = SiteUrl;


if (siteUrl != String.Empty) {


loadSharePointLists(siteUrl);


}


}




Add a Submit Button




IP forms are hosted in an aspx page or client application, so when the user wants to submit the form, he needs to have the submit button



a) create a connection to submit the xml data/string to the host environment (the host will handle the rest)



b) close the form so that it doesn’t just submit and stick around.




Add domain level trust




In InfoPath click on Tools->Form Options->Security and Trust




4. Create Code from your Form Schema




On the File menu, click Save As Source Files and save the form files in a folder on your local computer. There will be a file called myschema.xsd among the files you just saved.





Close InfoPath.



Open a Visual Studio 2005 Command Prompt which you can access via Start > Programs > Microsoft Visual Studio 2005 > Visual Studio Tools.



At the command-line prompt, use the cd command to navigate to the folder where you saved the form files. To generate a C# class for the form, at the command-line prompt type:




xsd myschema.xsd /c /l:cs 



This will create a C# file named myschema.cs for the InfoPath form.



Note: Once you have created the class and examine it, you will notice that the name of the class is the same as the name of the root node of the InfoPath form. So if you want the generated class to have a meaningful name other than myFields, which is the default name assigned to the root node of an InfoPath form, you must change the name of the root node in InfoPath to the name you want the generated class to have, before you create the .NET class.




5. Adapt your Workflow to use the Form






Add myschema.cs to the project



Publish the Form




In InfoPath click File –> Publish –> Select ‘To a network location” –> Browse to the root folder of the Workflow Project –> empty the url –> publish



Copy the dll from the Form Source Folder into the root folder of the Workflow Project




Adapt Workflow.xml





In MetaData add <Association_FormURN>[URN FOR ASSOCIATION FORM]</Association_FormURN>



Set the AssociationURL attribute of the Workflow element to the following value:




AssociationUrl="_layouts/CstWrkflIP.aspx"



Note: To get the Form ID open your Form in InfoPath click on File –> Properties



Note:




AssociationUrl="_layouts/CstWrkflIP.aspx" 

InstantiationUrl="_layouts/IniWrkflIp.aspx"


ModificationUrl="_layouts/WFMod.aspx"




Adapt Feature.xml




In the ElementManifest Tag add the xsn file and dll




<ElementFile Location="Foobar.dll"/> 

<ElementFile Location="Foobar.xsn"/>




6. Use Form Data in the Workflow





To use the information from the InfoPath Form within the workflow use the following code




//deserialise InfoPath initiation form data 
String initData = workflowProperties.InitiationData;
XmlSerializer xser = new XmlSerializer(typeof(ListSelector));
XmlTextReader reader = new XmlTextReader(new System.IO.StringReader(initData));
ListSelector listSelector = (ListSelector)xser.Deserialize(reader);




7. Attach the Workflow to you List or Library





Open the List –> Settings –> Workflow settings –> Add a Workflow –> Select the Workflow –> Enter a name –> Select the List and Start Options






After clicking OK you will see your form



image