Wednesday, August 31, 2011

Programmatically pass parameters to workflow

Hi All,
I worked on SharePoint workflow and explore many things.
Here I am going to share about SharePoint parameters i.e. 'Association Data' and 'Initiation Data'.
Association Data: - Association data is declared when administrator creating an association on site/list. This data is helpful to provide some default value, some constraints values or some other information.
Initiation Data: - When a user starts a workflow, some information input is required from the user. These inputs may override the association data default values or some additional input. These inputs are specific to current workflow instance and not available to other instances.
When workflow starts using SharePoint UI, workflow's forms are prompted (if any input is required). But sometimes we need to pass this information programmatically.  In this blog I am going to share my knowledge about "Pass parameters to workflow programmatically".
Workflow persist the data in the form of xml, but to use xml in code is difficult, so i am using classes to manage data in the code and further I convert the class object into xml by serialization.
1) Create a public class with at least default parameter less constructor.
2) Mark the class as serializable at the top of the class by [Serializable] attribute. This attribute allow class to be serialize.
3) Add public properties, each correspond to required input parameters.
4) Add two static methods for serialization and deserialization.
4) By xml serialization convert the class into xml.
5) Assign the xml to workflow data.
A sample class MyWFInitiationData with two properties 'Amount' and 'ApplicantEmail'
public class MyWFInitiationData {
      public MyWFInitiationData(){
      }
      public string ApplicantEmail{
      get; set;
      }
      public int Amount{
       get;   set;
      }
// As required can add more properties corresponding to the input from the user. MyWFInitiationData
static stringInitiationDataToXml(MyWFInitiationData param) {
    string data = string.Empty;
    MyWFInitiationData objParams = param;
    MemoryStream stream = new MemoryStream();
    XmlSerializer serial = newXmlSerializer(typeof(MyWFInitiationData));
    serial.Serialize(stream, objParams);
    Byte[] bytes = new Byte[stream.Length];
    bytes = stream.GetBuffer();
    data =Encoding.UTF8.GetString(bytes);
    return data;
}
// Deserialize the initiation data from xml to MyWFInitiationData object.
static MyWFInitiationData InitiationDataFromXml(string initiationXML) {
    if (initiationXML.Length > 0) {
    XmlSerializer serializer = new XmlSerializer(typeof(MyWFInitiationData));
    XmlTextReader textReader = new XmlTextReader(new System.IO.StringReader(initiationXML));
    MyWFInitiationData reminderInitData = new MyWFInitiationData();
    object obj = serializer.Deserialize(textReader);
  
    if(obj != null)
      reminderInitData = (MyWFInitiationData) obj;
  
     return reminderInitData;
    }
    else{
     return null;
    }
  }
}
===============Start a workflow programmatically============
MyWFInitiationData data = new MyWFInitiationData();
string initiationDataXML = MyWFInitiationData.InitiationDataToXml(data);
SPWorkflowAssociation workflowAssosiation  = web.GetAssociationByName("Your workflow name", [System.Globalization.CultureInfo]::CurrentCulture);
SPWeb web =SPContext.Current.Web;
//if your workflow is associated with any listitem, you should pass the listitem reference instead of 'web.Site.RootWeb'.
web.Site.WorkflowManager.StartWorkflow(web.Site.RootWeb, workflowAssosiation, initiationDataXML,
                                    SPWorkflowRunOptions.Synchronous);
 ==========Get Data inside the workflow=================
You de-serialize the data from xml to MyWFInitiationData class object at workflow activated event as mention below
MyWFInitiationData _initData = MyWFInitiationData.InitiationDataFromXml(workflowProperties.InitiationData);
Now using _initData.Amount & _initData.ApplicantEmail we can get the values inside the workflow.

Sharepiont Security Permission, Permission Levels etc....

As I worked on SharePoint security I always confused about the SharePoint security terms used in SharePoint class library. Here I am trying to blog SharePoint Security related terms like Permissions, Permissions Level, RoleDefination, Security Groups and Role Assignments which helps to explain the SharePoint classes.
  1. Permissions: - SharePoint Foundation doesn’t allow defining custom permission. SharePoint provides 35 predefined permission to create different permission levels. By grouping these permission together in different sets, can create different permission levels.
    You can get the more details of predefined permission at MSDN
  2. Permission Levels: - Permission Level is nothing but a set of different permissions. We can’t directly assign permissions to group/user, instead need to create permission level and it can be assign. By default SharePoint provides 5 permission levels. These are “Full Control”, “Design”, “Contributor”, “Read” & “Limited Access”. You can get more detail of default permission levels at MSDN.
  3. SharePoint Security Groups: - SharePoint allows adding active directory groups as well as admin can create SharePoint groups at site collection level. Each SharePoint group contains one or more user.
  4. RoleDefination: - Each SharePoint group/user should have one or more permission levels assign to it. Permission levels with SPGroup/User calls RoleDefination. In simple words when we assign permission levels to group/user, it defines a role for the corresponding group/user.
  5. RoleAssignment:- When an SharePoint group/user is added to SharePoint web, this process is called RoleAssignment. Adding a role assignment to web is the final stage of assigning a permission to group/user.
  6. Permission Inheritance:- As word 'Inheritance' say most of the thing about it. By default, SharePoint objects like Site Collection, Web, List & List Item are inherit permission from his parent object. It means user have all the permission on an SharePoint object that user have on parent object. If we want to child object have different permission then parent, we need to explicitly break the inheritance.