Wednesday, March 28, 2007

SPD Workflow activity : Creating a document library

Using the codesample of Todd Baginski's post of creating a custom activity to email, I modified the code to create a doclib using two variables that an user enters in SPD. These two variables are the url of the site and the title of the document library.

I replaced the code of Todd with this chunk :

using System;

using System.ComponentModel;
using System.ComponentModel.Design;
using System.Collections;
using System.Diagnostics;
using System.Drawing;
using System.Workflow.ComponentModel;
using System.Workflow.ComponentModel.Design;
using System.Workflow.ComponentModel.Compiler;
using System.Workflow.ComponentModel.Serialization;
using System.Workflow.Runtime;
using System.Workflow.Activities;
using System.Workflow.Activities.Rules;
using Microsoft.SharePoint;
 
namespace CreateDocumentLibrary
{
    public partial class Doclib: SequenceActivity
    {
 
        private EventLog _eventLog; 
 
        public static DependencyProperty UrlProperty = 
DependencyProperty.Register("Url", typeof(string), typeof(Doclib));
        public static DependencyProperty ListNameProperty = 
DependencyProperty.Register("ListName", typeof(string), typeof(Doclib));
 
 
        [ValidationOption(ValidationOption.Required)]
        public string Url
        {
            get
            {
                return (string)base.GetValue(UrlProperty);
            }
            set
            {
                base.SetValue(UrlProperty, value);
            }
        }
 
        [ValidationOption(ValidationOption.Required)]
        public string ListName
        {
            get
            {
                return (string)base.GetValue(ListNameProperty);
            }
            set
            {
                base.SetValue(ListNameProperty, value);
            }
        }
 
        protected override ActivityExecutionStatus 
Execute(ActivityExecutionContext executionContext)
        {
            //Set up the Event Logging object 
            _eventLog = new EventLog("Workflow");
            _eventLog.Source = "SharePoint Workflow";
 
            try
            {
                //Send the email 
                CreateList();
            }
            finally
            {
                //Dispose of the Event Logging object 
                _eventLog.Dispose();
            }
 
            //Indicate the activity has closed 
            return ActivityExecutionStatus.Closed;
        }
 
        private void CreateList()
        {
            try
            {
            SPSite site = new SPSite(Url);
            SPWeb rootweb = site.OpenWeb();
            SPListCollection lists = rootweb.Lists;
 
 
            SPListTemplateType listTemplateType = new SPListTemplateType();
            listTemplateType = SPListTemplateType.DocumentLibrary;
            lists.Add(ListName, "", listTemplateType);
         _eventLog.WriteEntry("Worklow succes: List 
created at: "
+ rootweb.Title.ToString());
            }
            catch (System.Exception Ex)
            {
                //Log exceptions in the Event Log 
                _eventLog.WriteEntry("Workflow Error :" + 
Ex.Message.ToString(), EventLogEntryType.Information);
            }
        } 
 
        public Doclib()
        {
            InitializeComponent();
        }
    }
}
 

And the XML to publish this code in SPD in the WSS.ACTIONS looks like:

 

<Action Name="Create Document Library"
ClassName="CreateDocumentLibrary.Doclib"
Assembly="CreateDocumentLibrary, Version=1.0.0.0, Culture=neutral, PublicKeyToken=54d1a6fdf526a294"
AppliesTo="all"
Category="Sample">
<RuleDesigner Sentence="Create document library %1 on %2.">
<FieldBind Field="Url" Text="Link to site" DesignerType="TextArea" Id="1"/>
<FieldBind Field="ListName" Text="Name of the doclib" Id="2" DesignerType="TextArea"/>
</RuleDesigner>
<Parameters>
<Parameter Name="Url" Type="System.String, mscorlib" Direction="In" />
<Parameter Name="ListName" Type="System.String, mscorlib" Direction="In" />
</Parameters>
</Action>

</Actions>

So if you want use this code, follow all the steps that are described in the post of Todd and replace his code and xml with mine and you could be a happy man! ;)

21 comments:

Sridhar Usha said...

This has been a very useful post Howeve I am not able to actually run the activity in the workflow . i get an workflow error and also I am not able to view the events in the event log. I coded the same way as in Todd's post. Any ideas

Robin Meuré said...

When does this error occur?
Is the workflow recognized in Sharepoint Designer and can you fill in all of the properties?

Anonymous said...

Code for CreateList() contains:

SPSite site = new SPSite(Url);
SPWeb rootweb = site.OpenWeb();

Conforming to the WSSv3 best practices it should contain Close() invocations for site and rootweb as well (ie. in finally section).
Ommiting these invocations lead to memory issues, because garbage collector does not collect site and web automatically.

Robin Meuré said...

Hi Tom,

you are absolutely right, 99% of the time I Close() and Dispose() my SPSite and SPWeb objects. Only this time you caught me ;)

Thanks!

André Rentes said...

Hi Robin,

Did you do a custom action where in WSS.ACTIONS has a parameter with Direction="Out"

Im having problems wiht this parameter type.

Thanks

Robin Meuré said...

Hi André,

what problems are you having?

André Rentes said...

I put a parameter with direction Out in WSS.ACTIONS, when open SPD show this parameter, I choose a variable but it not appear. I click in Check Workflow button and appear a exclamation error!

Can I to send a email for you with the wss.action and a print screen of SPD!?

Thanks Robin for the help. I dont found information about this and the Microsoft dont have documentation it

Robin Meuré said...

Yeah sure, you can find my email address in the profile section http://www.blogger.com/profile/06878262430984779866

Anonymous said...

Hi Robin, great article!

I tried to use this code, changing the classnames to protect the innocent :-) but what I see is that the second string (Name of doclib) will not stick. I can type it in, but when I leave the field, it reverts back to needing info again. Any ideas?

STom

Robin Meuré said...

Hi STom,

well i've had the same problem once as you did. What I did was:
1. Create a new project
2. Copy/pasted my code
3. Build it and registered as a new workflow action
4. It worked.

So I don't know what the cause was, hopes this helps you a bit though.

Anonymous said...

Hi,

Got the same problem. What I did:

1. Changed Assembly Version
2. Rebuilded and registered
3. Changed Assembly Version in Web.config and .ACTIONS file.

Everything worked fine...

Anonymous said...

Hello,

Everytime I run the workflow I get an error (the message is only "an error occured...) with the user SHAREPOINT\system.

Could this be a security issue?

Thanks!

Robin Meuré said...

Did you use the code to write error's to the eventlog of the server?

Anonymous said...

Yes, just pastet your code but I can't see any workflow related errors in the eventlog.

Anonymous said...

just tried the email activity from Todd Baginski and got the same error...

Robin Meuré said...

Hmm.. that is very weird. Tried to the change the security level of the web.config? So instead of WSS_Minimal change it to WSS_Medium or Full?

Anonymous said...

Unfortunately no success...
I also gave full control to the system account.

Anonymous said...

I havent tested it, but you probably need to elevate the privileges since it is probably running under the currents user account? You can use RunWithElevatedPrivileges or open the Site

Term Papers said...

I have been visiting various blogs for my term papers writing research. I have found your blog to be quite useful. Keep updating your blog with valuable information... Regards

phentermine works said...

Thanks for your modified source code!

Anonymous said...

Updated link to Todd's post (it's been moved)

http://www.toddbaginski.com/blog/archive/2007/03/09/how-to-create-a-custom-windows-workflow-activity-and.aspx