Tuesday, September 18, 2012

Sharepoint Custom Workflow Activity


Dear Friends,

           This blog is regarding creating "Sharepoint Custom Workflow Activity" through visual studio 2010. First, lets us have look on what is Custom Workflow Activity, what is need to create custom workflow activity?

          When creating workflow, Sharepoint designer supports out-of-box actions which can be easily used. Examples are Sending email, Creating item in List of same site, Log to history list, etc. Below are set of actions provided in Sharepoint designer:


Workflow Actions Out-of-box
          SharePoint Designer supports only a subset of the workflow activities available from the workflow foundation. The two most notable workflow activities that SharePoint does not support are the WhileActivity, which is responsible for looping, and the ReplicatorActivity, which is responsible for iterating through a collection. Other activities, though supported, have limited functionality. For instance, the LogToHistoryActivity, which is used to log messages to the Workflow History list, cannot write to the
Other Data field; therefore, messages from a SharePoint Designer–created workflow sent to the Workflow History list are capped at 256 characters. 


           If the limitations of SharePoint Designer are too restrictive, Visual Studio is the answer. With Visual Studio, you have complete access to the capabilities of the SharePoint Workflow host and workflow runtime. The designer in Visual Studio allows for looping and iteration—the two key reasons why most solutions require a Visual Studio workflow. 

           We need to go for creating Sharepoint Custom Workflow activity when Sharepoint designer does not support out-of-box inbuilt actions for workflow. We had requirement to add/create new item in sub site's list when workflow is triggered. Sharepoint designer workflow actions support adding item in same site list but when it comes to adding item in sub site list it doesn't support, so we need to create Sharepoint Custom Workflow activity. 

   Let's see how can we create Custom Workflow Activity:

  1.    Create a new project, select “Empty SharePoint Project” as the template.
  2. Creating Empty Sharepoint Project

    2. Give the project a cool name and click “OK.”
    3.  Select “Deploy as farm solution” in the wizard window.

    Sharepoint Deployment as Farm Solution

    4.   Add a reference to “Microsoft.SharePoint.WorkflowActions” from the .NET tab in the Add Reference dialog. 
     Add a reference to “System.Workflow.Activities”, “System.Workflow.ComponentModel” and “System.Workflow.Runtime” under “Browse” in the folder “Program Files (x86) Reference AssembliesMicrosoftFrameworkv3.0“

    Sharepoint Adding Reference


Once the project is configured, we will create the activity code as shown below:


Creating the Activity Code

  1. You now have a SharePoint solution with the proper references set so that you can write an Activity. It is time to add the class and the first bit of code.
  2. Add a new empty Class file to the project.                                                               In my case I given Class Name is “CustomSubsSiteAction” and that class Inherit with “Activity” Class.
Sharepoint Creating Custom Activity



   In order to allow properties to be passed in from SharePoint designer, you have to set up Dependency Properties.

2. Add a Property and Dependency Property for values that will come in from the Workflow. Below is code: 



public static DependencyProperty DepartMentsProperty = DependencyProperty.Register("DepartMents", typeof(string), typeof(CustomSubsSiteAction));
        [Category("Cross-Site Actions"), Browsable(true)]
        [DesignerSerializationVisibility
          (DesignerSerializationVisibility.Visible)]
        public string DepartMents
        {
            get
            {
                return Convert.ToString(base.GetValue(DepartMentsProperty));
            }
            set
            {
                base.SetValue(DepartMentsProperty, value);
            }
        }
 

When your activity starts, the Execute method is fired. This is where you will do the work in the Activity. So when can override Execute Method and Perform ours Operation.


protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)
        {
             // do stuff here.
            return ActivityExecutionStatus.Closed;
        }



But If we want to Access Current Item Like: List ID, List Item, Current Web than add Dependency Property for that. Access current site Context then Register Property as shown in code below:

public static DependencyProperty __ContextProperty = System.Workflow.ComponentModel.DependencyProperty.Register("__Context", typeof(WorkflowContext), typeof(CustomSubsSiteAction));

        [Description("The site context")]
        [Category("User")]
        [Browsable(true)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
        public WorkflowContext __Context
        {
            get
            {
                return ((WorkflowContext) (base.GetValue(CrossSubSiteAction.__ContextProperty)));
            }
            set
            {
                base.SetValue(CrossSubSiteAction.__ContextProperty, value);
            }
        }

  Same as Current List Item’s List ID:


public static DependencyProperty __ListIdProperty = System.Workflow.ComponentModel.DependencyProperty.Register("__ListId", typeof(string), typeof(CustomSubsSiteAction));

        [ValidationOption(ValidationOption.Required)]
        public string __ListId
        {
            get
            {
                return ((string)(base.GetValue(CrossSubSiteAction.__ListIdProperty)));
            }
            set
            {
                base.SetValue(CrossSubSiteAction.__ListIdProperty, value);
            }
        }


For Current ListItem’s ID:

public static DependencyProperty __ListItemProperty = System.Workflow.ComponentModel.DependencyProperty.Register("__ItemID", typeof(int), typeof(CustomSubsSiteAction));

        [ValidationOption(ValidationOption.Required)]
        public int __ ItemID
        {
            get
            {
                return ((int)(base.GetValue(CrossSubSiteAction.__ListItemProperty)));
            }
            set
            {
                base.SetValue(CrossSubSiteAction.__ListItemProperty, value);
            }
        }

Also,Register Workflow Activationproperties for Action.

public static DependencyProperty __ActivationPropertiesProperty = DependencyProperty.Register("__ActivationProperties", typeof(Microsoft.SharePoint.Workflow.SPWorkflowActivationProperties), typeof(CustomSubsSiteAction));



        [ValidationOption(ValidationOption.Required)]

        public Microsoft.SharePoint.Workflow.SPWorkflowActivationProperties __ActivationProperties

        {

            get

            {

                return (Microsoft.SharePoint.Workflow.SPWorkflowActivationProperties)base.GetValue(CrossSubSiteAction.__ActivationPropertiesProperty);

            }

            set

            {

                base.SetValue(CrossSubSiteAction.__ActivationPropertiesProperty, value);

            }


        }


Override Execute Method & have custom action code as shown below:


Sharepoint - Override Execute method of Action














 In order for SharePoint designer to know about the Activity, we have to add a special XML file to the Workflow folder in the SharePoint hive.


    1. Right-click on the Project and select Add -> SharePoint Mapped Folder…”

Adding Action to Sharepoint
                           
                   From the folder list, select “TEMPLATE/1033/Workflow“

Sharepoint Mapped Folder


In the Solution Explorer, right-click on the new Workflow folder and add an XML file (Add -> New Item -> DataXML File). And File name and file extension Must be “.actions”

 


Custom Actions XML
 Open CrossSiteAction.actions File and Add RuleDesigner,Parameter


Action Name :  Name="Access Cross Subs-Sites List"

Action showing In category  :  Category="Cross Sub-Site List"

In my case .actions file is



xml version="1.0" encoding="utf-8" ?>

<WorkflowInfo>

  <Actions>

    <Action Name="Access Cross Subs-Sites List"

    ClassName="CustomSubsSiteAction.CustomSubsSiteAction"

    Assembly="CustomSubsSiteAction, Version=1.0.0.0, Culture=neutral, PublicKeyToken=7341b1706fa0e582"

   AppliesTo="all" Category="Cross Sub-Site List">

      <RuleDesigner Sentence="Add Current-Listitem to DepartMentName = %1 Task Listitem">       

        <FieldBind Field="DepartMents" DesignerType="TextArea" Id="1" />    

      </RuleDesigner>

      <Parameters>       

        <Parameter Name="__Context" Type="Microsoft.SharePoint.WorkflowActions.WorkflowContext" Direction="In" />

        <Parameter Name="__ListId" Type="System.String, mscorlib" Direction="In" />

        <Parameter Name="__ItemID" Type="System.Int32, mscorlib" Direction="In" />

 <Parameter Name="DepartMents" Type="System.String, mscorlib"  Direction="In" /> 
<Parameter Name="__ActivationPropertiesType="Microsoft.SharePoint.Workflow.SPWorkflowActivationProperties, Microsoft.SharePoint" Direction="Out" />
      </Parameters>
    </Action>
  </Actions>
</WorkflowInfo>


Deploying & Register your Namespace for Authorization 

Deploy the solution & to register Custom Activites to Webapplication's Web.Config File

between tab


Web config




Than Restart IIS.

Open run and just write IISreset and Ok.

Now Open Sharepoint Designer 2010 & Go to workflow

Sharepoint Custom workflow Action

Please let me know if anyone has any queries.


Thanks & Regards, 

Paras Sanghani

Source Code

Monday, September 10, 2012

Sharepoint Object Hierarchy

Dear Friends,

               In my previous post on Sharepoint 2010 platform, we discussed about Sharepoint 2010 platform, its architecture and advantages. Now, we will have detailed look on Sharepoint objects which as Sharepoint developers, we would be dealing with.







Figure: Sharepoint Server Architecture

  1. The SPFarm object is the highest object within the SharePoint Foundation object model hierarchy. The Servers property gets a collection representing all the servers in the deployment, and the Services property gets a collection representing all the services.
  2. Each SPServer object represents a physical server computer. The ServiceInstances property provides access to the set of individual service instances that run on the individual computer.
  3. Each SPService object represents a logical service installed in the server farm. Derived types of the SPService class include, for example, objects for Windows services, such as the timer service, search, the database service, etc. and also objects for Web services, such as the basic content publishing Web service which supports the Web applications.
  4. An SPWebService object provides access to configuration settings for a specific logical service or application. The WebApplications property gets the collection of Web applications that run the service.
  5. If the service implements the Service Application Framework of SharePoint Foundation, then it can be split into multiple configured farm-scoped instantiations (CFSIs). Each of these provides the functionality of the service but each has its own individual permission and provisioning settings.
  6. Each instance of a service, or a CFSI, that is running on a specific server is represented by an SPServiceInstance object.
  7. An SPDatabaseServiceInstance object represents a single instance of a database service running on the database server computer. The SPDatabaseServiceInstance class derives from the SPServiceInstance class and thus inherits the Service property, which provides access to the service or application that the instance implements. The Databases property gets the collection of content databases used in the service.
  8. Each SPWebApplication object represents a Web application hosted in an Internet Information Services (IIS) Web site. The SPWebApplication object provides access to credentials and other farm-wide application settings. The Sites property gets the collection of site collections within the Web application, and the ContentDatabases property gets the collection of content databases used in the Web application.
  9. An SPContentDatabase object inherits from the SPDatabase class and represents a database that contains user data for a Web application. The Sites property gets the collection of site collections for which the content database stores data, and the WebApplication property gets the parent Web application.
  10. An SPSiteCollection object represents the collection of site collections within the Web application.
 

        
Figure: Sharepoint site Architecture



1.  Each SPSiteobject, despite its singular name, represents a set of logically related SPWeb objects. Such a set is commonly called a "site collection," but SPSite is not a standard Microsoft .NET collection class, in contrast to SPWebCollection. Rather, it has members that can be used to manage the site collection. The AllWebs property provides access to the SPWebCollection object that represents the collection of all Web sites within the site collection, including the top-level site. The SPSite.OpenWebmethod of the SPSite class returns a specific Web site.
2. Each site collection includes any number of SPWeb objects, and each object has members that can be used to manage a site, including its template and theme, as well as to access files and folders on the site. The Webs property returns an SPWebCollection object that represents all the subsites of a specified site, and the Lists property returns an SPListCollection object that represents all the lists in the site.
3.  Each SPList object has members that are used to manage the list or access items in the list. The GetItems method can be used to perform queries that return specific items. The Fields property returns an SPFieldCollection object that represents all the fields, or columns, in the list, and the Items property returns an SPListItemCollection object that represents all the items, or rows, in the list.
4.  Each SPField object has members that contain settings for the field.
5.  Each SPListItem object represents a single row in the list.

Sharepoint 2010 Object Hierarchy
Microsoft SharePoint 2010 offers a highly structured server-side object model that makes it easy to access objects that represent the various aspects of a SharePoint Web site. From higher-level objects, you can drill down through the object hierarchy to obtain the object that contains the members you need to use in your code. These objects are listed below:
  • SPFarm Objects
  • SPServer Objects
  • SPService Objects
  • SPWebApplication Objects
  • SPSite Objects
  • SPWeb Objects
  • SPList Objects

1.1   SPFarm Object


The SPFarm object is the top level or root object in the hierarchy, which is designed to interact with the configuration data store. It contains global settings for all the servers, services, and solutions that are installed in a server farm.
Its Servers property contains a collection representing all the servers in the environment, and similarly the Services property has a collection representing all the services.
You can get the current top-level server farm object as follows:

SPFarm myFarm = SPContext.Current.Site.WebApplication.Farm;
To get a reference to either the server farm or the current physical server, you can use the following static properties:

Microsoft.SharePoint.Administration.SPFarm.Local or
Microsoft.SharePoint.Administration.SPServer.Local.
SPFarm myFarm = SPFarm.Local;
“SPFarm.Local provides the entry point to the current farm”
The term physical object does not necessarily mean that the objects exist separately on disk. SharePoint stores all objects in the content database. You may consider a physical object as something that might exist (such as a server machine) or that can be stored elsewhere (such as a file).
The SPFarm class has three child classes:
  1. SPServer, which represents a single server within the farm;
  2. SPService, which gives access to the farm’s services; and
  3. SPSolution, which is used to deploy something to the farm.
SPFarm is closely related to the configuration database. For instance, the “DisplayName” property of the SPFarm object returns the name of the configuration database. Like many other objects, SPFarm inherits from SPPersistedObject, which means the object’s data is persisted in the configuration database. That’s the reason so many objects have static properties returning useful information without any visible connection to other objects. They simply pull the data from the configuration database.


1.1   SPServer Object


Each physical server computer is represented by an SPServer type.  The ”ServiceInstances” property provides access to the set of individual service instances that run on the individual computers, each as an SPService type.

Typical properties of an SPServer object are the IP address (Address property) and the Role property.
Role returns an enumeration of type SPServerRole:
  •  Application: The server runs a web application.
  •  Invalid: The server has not yet registered any role in the configuration database.
  • SingleServer: The server is the only server in the farm (also called single-server installation).
  •  WebFrontEnd: The server is a regular front-end server in the farm.
As for SPFarm, the SPServer object has a static property, Local, that represents the local machine:

SPServer myserver = SPServer.Local;
Using the constructor with a server’s address, you can instantiate any server’s object from:

SPServer myserver = new SPServer(“myfarm-dev64″);
SPServer’s ServicesInstances property returns all its services. This includes SharePoint’s Windows and web services.
    

1.2   SPService Object


Each SPService object represents a logical service or application installed in the server farm. A service object provides access to farm-wide settings of the load-balanced service that a respective service instance implements. Derived types of the SPService class include, for example, objects for Windows services, such as the timer service, search, Microsoft SQL Server, the database service, and objects for web services.

All services have the SPService base class. The most confusing thing here is that both Windows services and web services inherit from same base class.

Moreover, the SharePoint-specific services, such as incoming e-mail, are in the same class hierarchy. This is another class that inherits from SPPersistedObject, ensuring persistence in the configuration database. The class provides members that return the assigned and currently running jobs. Most services process jobs in a queue. A service can have multiple instances. The Instances property returns them, and the SPServiceInstance class defines the objects representing an instance. An instance can be started or stopped.

Several web services support features provided by the API as well. The major difference is that web services can be used remotely. The API access is only possible if the code is executed on the target machine. The internal services that SharePoint provides can be configured in several ways. These services are:
  • Web Application service
  • Administration service
  • Timer service
  • Diagnostics service
  • Central Administration service
  • Search service
  • Outgoing E-mail service
  • Incoming E-mail service
  • User Code service
  • Database service
Front-end servers usually run services such as the Web Application service. Application servers with a dedicated function run the Search service, for instance. Depending on the entire farm configuration, the services spread across the farm. The criteria to let one or another service run on a specific machine depend on the expected performance and physical capabilities of the hardware. If you know that the Search service takes 80 percent of the CPU power, then it would be unwise to locate it on the same machine as the front-end server.
From the class model perspective, the services structure has five specific variants:
  1. Windows services (SPWindowsService)
  2. Web services (SPWebService)
  3. Diagnostic services (SPDiagnosticService)
  4. Outgoing E-mail services (SPOutboundEmailService)
  5. Incoming E-mail services (SPIncomingEmailService)
All these classes inherit from SPService. To investigate the current configuration of all services within the farm, the following code snippet is helpful. It consists of a small console application:

SPServiceCollection services = SPFarm.Local.Services;
foreach (SPService service in services)
{
             SPRunningJobCollection runningJobs = service.RunningJobs;
}
Services provide specific functions. The execution can be scheduled by a job. A job can be launched by a timer—either regularly (e.g., every 12 hours) or at a specific time (e.g., Monday at 7:00 p.m.)—or triggered by an event. They execute either on one server or on several servers on the farm, depending on
the purpose of the service.

1.3   SPWebApplication Object


Each SPWebApplication object represents a load-balanced web application based on IIS. The SPWebApplication object provides access to credentials and other server farm–wide application settings.

The Sites property contains the collection of sites or site collections within the web application, and the ContentDatabases property is a collection of content databases used in the web application. The SPWebApplication class replaces the obsolete SPVirtualServer class, but it can still be helpful to think of an SPWebApplication object as a virtual server—that is, a set of one or more physical servers that appear as a single server to users.

The top-level object, SPWebApplication, represents a whole application. Usually this object is directly related to at least one content database.  SPWebApplication inherits from SPWebService, because an application is treated internally like a service.

The ContentDatabases property returns a collection of content database represented by SPContentDatabase objects. Each web application is hosted in IIS; hence, the IisSettings property gives convenient access to the settings without needing a connection to IIS.

Similarly, the ApplicationPool property gives access to the application pool.

SPWebApplication is another object that inherits from SPPersistedObject, meaning that the object’s data is persisted in the configuration database.

You can get an SPWebApplication object by different methods. Within a SharePoint application, you can use the current context:

SPWebApplication web = SPContext.Current.Site.WebApplication;
From anywhere else, such as a console application, use the following:

SPWebApplication web = new SPSite(“http://myserver/site”).WebApplication;
You’ve already learned that any request is handled by an ASP.NET application and represented by an HttpApplication object. SharePoint has its own implementation, SPHttpApplication, which is tightly coupled to SPWebApplication. Each web application runs its own SPHttpApplication object. The content stored with the features provided by a web application is held within one or more content databases. Each database object has, along with the web application object, references to one or more SPSite objects.

1.4   SPSite Object

An SPSite object represents the collection of site collections within the web application. The Item property or indexer gets a specified site collection from the collection, and the Add method creates a site collection within the collection.

Each SPSite object, despite its singular name, represents a set of logically related SPWeb objects. Such a set is commonly called a site collection, but SPSite is not a typical collection class, like SPWebCollection. Instead, it has members that can be used to manage the site collection.

The AllWebs property provides access to the SPWebCollection object that represents the collection of all web sites within the site collection, including the top-level site. The Microsoft.SharePoint.SPSite.OpenWeb method of the SPSite class returns a specific web site.
If your application does not run inside the context of a SharePoint site, you have to retrieve the Site object based on its URL:

SPSite mySiteCollection = new SPSite(“AbsoluteURL”);

1.5   SPWeb Object


Each site collection includes any number of SPWeb objects, and each object has members that can be used to manage a site, including its template and theme, as well as to access files and folders on the site. The Webs property returns an SPWebCollection object that represents all the subsites of a specified site, and the Lists property returns an SPListCollection object that represents all the lists in the site.

To return the top-level web site of the current site collection, use the RootWeb property:

SPWeb topSite = SPContext.Current.Site.RootWeb;
The SPContext class does not limit you to getting the current object of any given type. You can use the Microsoft.SharePoint.SPSite.AllWebs property to obtain a reference to any other web site than the current one. The following code returns the context of a specified site by using an indexer with the AllWebs property:

SPWeb webSite = SPContext.Current.Site.AllWebs["myOtherSite"];

1.6   SPList Object


Each SPList object has members that are used to manage the list or access items in the list. The GetItems method can be used to perform queries and retrieve items from the list. The Fields property of an SPList returns an SPFieldCollection object that represents all the fields, or columns, in the list, and the Items property returns an SPListItemCollection object that represents all the items, or rows, in the list.



We will continue this series of Sharepoint development for beginners.


Thanks,
Paras Sanghani