<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogit.create.pt/utility/FeedStylesheets/atom.xsl" media="screen"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en"><title type="html">Miguel Isidoro</title><subtitle type="html">.NET&lt;br /&gt;
SharePoint&lt;br /&gt;
Tek</subtitle><id>http://blogit.create.pt/blogs/miguelisidoro/atom.aspx</id><link rel="alternate" type="text/html" href="http://blogit.create.pt/blogs/miguelisidoro/default.aspx" /><link rel="self" type="application/atom+xml" href="http://blogit.create.pt/blogs/miguelisidoro/atom.aspx" /><generator uri="http://communityserver.org" version="2.1.60809.935">Community Server</generator><updated>2007-12-09T09:40:45Z</updated><entry><title>SharePoint 2007 Workflow - Using the OnWorkflowItemDeleted activity</title><link rel="alternate" type="text/html" href="http://blogit.create.pt/blogs/miguelisidoro/archive/2009/02/07/SharePoint-2007-Workflow-_2D00_-Using-the-OnWorkflowItemDeleted-activity.aspx" /><id>http://blogit.create.pt/blogs/miguelisidoro/archive/2009/02/07/SharePoint-2007-Workflow-_2D00_-Using-the-OnWorkflowItemDeleted-activity.aspx</id><published>2009-02-07T21:03:48Z</published><updated>2009-02-07T21:03:48Z</updated><content type="html">&lt;h5&gt;Introduction&lt;/h5&gt;  &lt;p&gt;One of the most exciting features included in SharePoint 2007 is workflow support and the possibility of developing our own custom workflows (for more information about workflow development in the SharePoint 2007 platform please click &lt;a href="http://msdn.microsoft.com/en-us/library/ms549489.aspx" target="_blank"&gt;here&lt;/a&gt;). &lt;/p&gt;  &lt;p&gt;While it is possible to develop workflows to automate a series of activities without any human intervention, the full power of workflows in the SharePoint platform can only be achieved with human-oriented workflows. These workflows are characterized by creating and assigning tasks to users that must complete them in order to fulfill the purpose of the workflow. Some examples of out of the box human-oriented workflows that are included with MOSS 2007 are Approval, Collect Feedback and Issue Tracking.&lt;/p&gt;  &lt;p&gt;In the SharePoint world, the most common usage of human-oriented workflows is in the context of document libraries, to perform some work when a new document is uploaded into a document library. Typically, in such scenario, tasks are created and assigned to users throughout the workflow lifetime that will complete them until the workflow purpose has been fulfilled. Having the workflow goal to be achieved is the desired and most common scenario, but unexpected actions may occur before the end of the workflow such as a user to delete the document. The following example will show you how to handle this situation in a custom workflow by using the OnWorkflowItemDeleted activity.&lt;/p&gt;  &lt;h5&gt;Example&lt;/h5&gt;  &lt;p&gt;The OnWorkflowItemDeleted activity can be used within a custom workflow to handle an item deletion in any SharePoint list. In this example, this activity will be used to delete all uncompleted tasks associated with the deleted item. After dragging and dropping the OnWorkflowItemDeleted activity into the workflow designer, the Invoke property must be set to the event handler that will perform the work. &lt;/p&gt;  &lt;p&gt;For the purpose of this example, please consider the simple approval workflow in the following image:&lt;/p&gt;  &lt;p&gt;&lt;img src="http://pic90.picturetrail.com/VOL2147/10903553/19399056/354040008.jpg" /&gt; &lt;/p&gt;  &lt;p&gt;In this workflow, a parallel activity with two branches is used. One contains the main workflow logic while the other contains a OnWorkflowItemDeleted activity that will handle the item deletion. The Invoke event property was set to be handled by an event handler method called OnWorkflowItemDeleted_Invoked. Let's take a look at the code:&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;public sealed partial class &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;ApprovalWorkflow &lt;/span&gt;: SequentialWorkflowActivity
{
    &lt;span style="color:gray;"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color:green;"&gt;Handles the workflow item deleted event.
    &lt;/span&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name=&amp;quot;sender&amp;quot;&amp;gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;param name=&amp;quot;e&amp;quot;&amp;gt;&amp;lt;/param&amp;gt;
    &lt;/span&gt;&lt;span style="color:blue;"&gt;private void &lt;/span&gt;OnWorkflowItemDeleted_Invoked(&lt;span style="color:blue;"&gt;object &lt;/span&gt;sender, ExternalDataEventArgs e)
    {
        &lt;span style="color:green;"&gt;//delete uncompleted tasks when 
        //an item is deleted
        &lt;/span&gt;SPWorkflow workflowInstance = 
            workflowProperties.Workflow;
        SPWorkflowTaskCollection taskCollection = 
            GetWorkflowTasks(workflowInstance);
        &lt;span style="color:blue;"&gt;for &lt;/span&gt;(&lt;span style="color:blue;"&gt;int &lt;/span&gt;i = taskCollection.Count; i &amp;gt; 0; i--)
        {
            SPWorkflowTask task = 
                taskCollection[i - 1];
            &lt;span style="color:blue;"&gt;using &lt;/span&gt;(SPWeb web = 
                workflowProperties.Web)
            {
                &lt;span style="color:blue;"&gt;if &lt;/span&gt;(task[SPBuiltInFieldId.TaskStatus]
                    .ToString() != SPResource.GetString
                    (&lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;CultureInfo&lt;/span&gt;((&lt;span style="color:blue;"&gt;int&lt;/span&gt;)web.Language, &lt;span style="color:blue;"&gt;false&lt;/span&gt;),
                    &lt;span style="color:#a31515;"&gt;&amp;quot;WorkflowTaskStatusComplete&amp;quot;&lt;/span&gt;, &lt;span style="color:blue;"&gt;new object&lt;/span&gt;[0]))
                {
                    task.Delete();
                }
            }
        }
    }

    &lt;span style="color:gray;"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color:green;"&gt;Reads the workflow tasks. This method 
    &lt;/span&gt;&lt;span style="color:gray;"&gt;/// &lt;/span&gt;&lt;span style="color:green;"&gt;is implemented because the Tasks property
    &lt;/span&gt;&lt;span style="color:gray;"&gt;/// &lt;/span&gt;&lt;span style="color:green;"&gt;of the SPWorkflow instance takes a 
    &lt;/span&gt;&lt;span style="color:gray;"&gt;/// &lt;/span&gt;&lt;span style="color:green;"&gt;while to be populated.
    &lt;/span&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;/summary&amp;gt;
    &lt;/span&gt;&lt;span style="color:blue;"&gt;public static &lt;/span&gt;SPWorkflowTaskCollection 
        GetWorkflowTasks(SPWorkflow workflowInstance)
    {
        SPWorkflowTaskCollection taskCollection = &lt;span style="color:blue;"&gt;null&lt;/span&gt;;
        &lt;span style="color:blue;"&gt;bool &lt;/span&gt;tasksPopulated = &lt;span style="color:blue;"&gt;false&lt;/span&gt;;
        &lt;span style="color:blue;"&gt;while &lt;/span&gt;(!tasksPopulated)
        {
            &lt;span style="color:blue;"&gt;try
            &lt;/span&gt;{
                taskCollection = workflowInstance.Tasks;
                tasksPopulated = &lt;span style="color:blue;"&gt;true&lt;/span&gt;;
            }
            &lt;span style="color:blue;"&gt;catch &lt;/span&gt;{ }
        }

        &lt;span style="color:blue;"&gt;return &lt;/span&gt;taskCollection;
    }
}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;In the previous example, the following actions are being performed:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;In the OnWorkflowItemDeleted_Invoked event handler, the workflow instance task collection is obtained by calling the GetWorkflowTasks method;&lt;/li&gt;

  &lt;li&gt;The task collection is iterated and the each task status is checked to verify if it is still uncompleted;&lt;/li&gt;

  &lt;li&gt;If so, the task is deleted.&lt;/li&gt;
&lt;/ul&gt;&lt;img src="http://blogit.create.pt/aggbug.aspx?PostID=1649" width="1" height="1"&gt;</content><author><name>misidoro</name><uri>http://blogit.create.pt/members/misidoro.aspx</uri></author><category term="Sharepoint 2007" scheme="http://blogit.create.pt/blogs/miguelisidoro/archive/tags/Sharepoint+2007/default.aspx" /><category term="WSS" scheme="http://blogit.create.pt/blogs/miguelisidoro/archive/tags/WSS/default.aspx" /><category term="Windows Workflow" scheme="http://blogit.create.pt/blogs/miguelisidoro/archive/tags/Windows+Workflow/default.aspx" /></entry><entry><title>SharePoint 2007 - Updating List Content Types Event Handlers on Site Content Type Update</title><link rel="alternate" type="text/html" href="http://blogit.create.pt/blogs/miguelisidoro/archive/2009/01/11/SharePoint-2007-_2D00_-Updating-List-Content-Types-Event-Handlers-on-Site-Content-Type-Update.aspx" /><id>http://blogit.create.pt/blogs/miguelisidoro/archive/2009/01/11/SharePoint-2007-_2D00_-Updating-List-Content-Types-Event-Handlers-on-Site-Content-Type-Update.aspx</id><published>2009-01-11T20:53:53Z</published><updated>2009-01-11T20:53:53Z</updated><content type="html">&lt;h5&gt;Introduction&lt;/h5&gt;  &lt;p&gt;One of the areas where the SharePoint 2007 platform (both WSS 3.0 and MOSS 2007) still needs to improve is deployment despite all the major improvements made when compared to its antecessor, the 2003 version. One of the faults I ran recently into is related with updating list content types event handlers when site content types event handlers are updated.&lt;/p&gt;  &lt;p&gt;For those who don't know, let's start by a brief introduction about content types and explain the difference between a site content type and a list content type. Content types are a new concept introduced in SharePoint 2007 and is basically a reusable collection of settings that can be applied to a certain category of content. Content types basically define the metadata (they are composed by a reusable set of columns called site columns) and behaviors (event handlers, workflows, etc) of a certain category of content. They are stored centrally and are reusable throughout a site or site collection depending on its scope. For more information about content types please click &lt;a href="http://msdn.microsoft.com/en-us/library/ms472236.aspx" target="_blank"&gt;here&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;So what is the difference between a site content type and a list content type? Probably, the easiest way to explain this is to think of site content types as templates (in the sense that they are reusable) and list content types as instances of those templates. Site content types are defined at the site level and are visible to the site where they are created and all its subsites (this concept is called content type scope) and they are reusable and not bound to any specific list, meaning that they can be associated with any list within the sites under its scope. When a site content type is associated with a list, a copy of the site content type is copied into the list, creating a new instance. This instance is called a list content type.&lt;/p&gt;  &lt;h5&gt;Example&lt;/h5&gt;  &lt;p&gt;The best approach to deploy content types is to use features (for more information about deploying site content types as a feature please click &lt;a href="http://blogit.create.pt/blogs/andrevala/archive/2008/03/27/SharePoint-2007-Deployment_3A00_-Site-Content-Type-Features.aspx" target="_blank"&gt;here&lt;/a&gt;). Registering content type event handlers can also be achieved using a feature (check this &lt;a href="http://msdn.microsoft.com/en-us/library/ms475328.aspx" target="_blank"&gt;article&lt;/a&gt; for more information) or by using Patrick Tisseghem's &lt;a href="http://www.u2u.info/Blogs/Patrick/Lists/Posts/Post.aspx?ID=1547" target="_blank"&gt;Event Handler Explorer&lt;/a&gt;. The problem is when there are already list content types based on a site content type and we need to add a new event handler to it and have all list content types also updated. In my experience, both using the feature model approach or using Patrick's application didn't update the list content types. The remainder of this post will show you how to do this programmatically.&lt;/p&gt;  &lt;p&gt;The following example basically uses a console application to register a event handler and associate it to a content type.&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;class &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Program
&lt;/span&gt;{
    &lt;span style="color:blue;"&gt;private const string &lt;/span&gt;URL = &lt;span style="color:#a31515;"&gt;&amp;quot;http://myIntranet&amp;quot;&lt;/span&gt;;
    &lt;span style="color:blue;"&gt;private const string &lt;/span&gt;CONTENT_TYPE = &lt;span style="color:#a31515;"&gt;&amp;quot;MyContentType&amp;quot;&lt;/span&gt;;
    &lt;span style="color:blue;"&gt;private const string &lt;/span&gt;EVENT_RECEIVER_NAME = &lt;span style="color:#a31515;"&gt;&amp;quot;MyEventReceiver&amp;quot;&lt;/span&gt;;
    &lt;span style="color:blue;"&gt;private const string &lt;/span&gt;EVENT_RECEIVER_ASSEMBLY =
        &lt;span style="color:#a31515;"&gt;&amp;quot;MyEventReceivers.MyEventReceiver, MyEventReceiver, &amp;quot; &lt;/span&gt;+
        &lt;span style="color:#a31515;"&gt;&amp;quot;Version=1.0.0.0, Culture=neutral, PublicKeyToken=5989549632a535cf&amp;quot;&lt;/span&gt;;
    &lt;span style="color:blue;"&gt;private const string &lt;/span&gt;EVENT_RECEIVER_CLASS_NAME = 
        &lt;span style="color:#a31515;"&gt;&amp;quot;MyEventReceivers.MyEventReceiver&amp;quot;&lt;/span&gt;;

    &lt;span style="color:blue;"&gt;static void &lt;/span&gt;Main(&lt;span style="color:blue;"&gt;string&lt;/span&gt;[] args)
    {
        &lt;span style="color:green;"&gt;//open site collection
        &lt;/span&gt;&lt;span style="color:blue;"&gt;using &lt;/span&gt;(&lt;span style="color:#2b91af;"&gt;SPSite &lt;/span&gt;siteCollection = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;SPSite&lt;/span&gt;(URL))
        {
            &lt;span style="color:blue;"&gt;using &lt;/span&gt;(&lt;span style="color:#2b91af;"&gt;SPWeb &lt;/span&gt;site = siteCollection.OpenWeb())
            {
                &lt;span style="color:green;"&gt;//get content type
                &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;SPContentType &lt;/span&gt;contentType = 
                    site.ContentTypes[CONTENT_TYPE];
                &lt;span style="color:green;"&gt;// add ItemUpdating event handler
                &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;ContentTypeHelper&lt;/span&gt;.AddEventHandler(contentType, 
                    EVENT_RECEIVER_NAME, EVENT_RECEIVER_ASSEMBLY, 
                    EVENT_RECEIVER_CLASS_NAME, 10000, 
                    &lt;span style="color:#2b91af;"&gt;SPEventReceiverInstallerType&lt;/span&gt;.ItemUpdating);

                site.Update();
            }
        }
    }
}&lt;/pre&gt;

&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;internal class &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;ContentTypeHelper
&lt;/span&gt;{
    &lt;span style="color:gray;"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color:green;"&gt;Register an event handler in a list
    &lt;/span&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name=&amp;quot;contentType&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;SharePoint Content Type&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;param name=&amp;quot;receiverName&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;Event receiver name&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;param name=&amp;quot;className&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;Event handler class name&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;param name=&amp;quot;sequenceNumber&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;Sequence number&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
    &lt;/span&gt;&lt;span style="color:blue;"&gt;public static void &lt;/span&gt;AddEventHandler(&lt;span style="color:#2b91af;"&gt;SPContentType &lt;/span&gt;contentType, 
        &lt;span style="color:blue;"&gt;string &lt;/span&gt;receiverName, &lt;span style="color:blue;"&gt;string &lt;/span&gt;assemblyName, 
        &lt;span style="color:blue;"&gt;string &lt;/span&gt;className, &lt;span style="color:#2b91af;"&gt;Int32 &lt;/span&gt;sequenceNumber, 
        &lt;span style="color:#2b91af;"&gt;SPEventReceiverInstallerType &lt;/span&gt;eventReceiverInstallerType)
    {
        &lt;span style="color:green;"&gt;//get assembly full name
        &lt;/span&gt;&lt;span style="color:blue;"&gt;string &lt;/span&gt;assemblyFullName = System.Reflection.&lt;span style="color:#2b91af;"&gt;Assembly
            &lt;/span&gt;.GetAssembly(&lt;span style="color:#2b91af;"&gt;Type&lt;/span&gt;.GetType(assemblyName)).FullName;

        &lt;span style="color:green;"&gt;// remove existing event handlers
        &lt;/span&gt;RemoveEventHandlers(contentType, assemblyFullName);

        &lt;span style="color:#2b91af;"&gt;SPEventReceiverDefinition &lt;/span&gt;receiverDefinition = &lt;span style="color:blue;"&gt;null&lt;/span&gt;;

        &lt;span style="color:green;"&gt;//ItemAdding event handler
        &lt;/span&gt;&lt;span style="color:blue;"&gt;if &lt;/span&gt;(&lt;span style="color:#2b91af;"&gt;SPEventReceiverInstallerTypeHelper&lt;/span&gt;.CheckOption
            (eventReceiverInstallerType, 
            &lt;span style="color:#2b91af;"&gt;SPEventReceiverInstallerType&lt;/span&gt;.ItemAdding))
        {
            &lt;span style="color:green;"&gt;// add ItemAdding event handler
            &lt;/span&gt;receiverDefinition = contentType.EventReceivers.Add();
            receiverDefinition.Name = receiverName;
            receiverDefinition.Type = 
                &lt;span style="color:#2b91af;"&gt;SPEventReceiverType&lt;/span&gt;.ItemAdding;
            receiverDefinition.Assembly = assemblyFullName;
            receiverDefinition.Class = className;
            receiverDefinition.SequenceNumber = sequenceNumber;
            receiverDefinition.Update();
        }

        &lt;span style="color:green;"&gt;//ItemAdded event handler
        &lt;/span&gt;&lt;span style="color:blue;"&gt;if &lt;/span&gt;(&lt;span style="color:#2b91af;"&gt;SPEventReceiverInstallerTypeHelper&lt;/span&gt;.CheckOption
            (eventReceiverInstallerType, 
            &lt;span style="color:#2b91af;"&gt;SPEventReceiverInstallerType&lt;/span&gt;.ItemAdded))
        {
            &lt;span style="color:green;"&gt;// add ItemAdded event handler
            &lt;/span&gt;receiverDefinition = contentType.EventReceivers.Add();
            receiverDefinition.Name = receiverName;
            receiverDefinition.Type = 
                &lt;span style="color:#2b91af;"&gt;SPEventReceiverType&lt;/span&gt;.ItemAdded;
            receiverDefinition.Assembly = assemblyFullName;
            receiverDefinition.Class = className;
            receiverDefinition.SequenceNumber = sequenceNumber;
            receiverDefinition.Update();
        }

        &lt;span style="color:green;"&gt;//ItemUpdating event handler
        &lt;/span&gt;&lt;span style="color:blue;"&gt;if &lt;/span&gt;(&lt;span style="color:#2b91af;"&gt;SPEventReceiverInstallerTypeHelper&lt;/span&gt;.CheckOption
            (eventReceiverInstallerType, 
            &lt;span style="color:#2b91af;"&gt;SPEventReceiverInstallerType&lt;/span&gt;.ItemUpdating))
        {
            &lt;span style="color:green;"&gt;// add ItemUpdating event handler
            &lt;/span&gt;receiverDefinition = contentType.EventReceivers.Add();
            receiverDefinition.Name = receiverName;
            receiverDefinition.Type = 
                &lt;span style="color:#2b91af;"&gt;SPEventReceiverType&lt;/span&gt;.ItemUpdating;
            receiverDefinition.Assembly = assemblyFullName;
            receiverDefinition.Class = className;
            receiverDefinition.SequenceNumber = sequenceNumber;
            receiverDefinition.Update();
        }

        &lt;span style="color:green;"&gt;//ItemUpdated event handler
        &lt;/span&gt;&lt;span style="color:blue;"&gt;if &lt;/span&gt;(&lt;span style="color:#2b91af;"&gt;SPEventReceiverInstallerTypeHelper&lt;/span&gt;.CheckOption
            (eventReceiverInstallerType, 
            &lt;span style="color:#2b91af;"&gt;SPEventReceiverInstallerType&lt;/span&gt;.ItemUpdated))
        {
            &lt;span style="color:green;"&gt;// add ItemUpdating event handler
            &lt;/span&gt;receiverDefinition =contentType.EventReceivers.Add();
            receiverDefinition.Name = receiverName;
            receiverDefinition.Type = 
                &lt;span style="color:#2b91af;"&gt;SPEventReceiverType&lt;/span&gt;.ItemUpdated;
            receiverDefinition.Assembly = assemblyFullName;
            receiverDefinition.Class = className;
            receiverDefinition.SequenceNumber = sequenceNumber;
            receiverDefinition.Update();
        }

        &lt;span style="color:green;"&gt;//ItemCheckingIn event handler
        &lt;/span&gt;&lt;span style="color:blue;"&gt;if &lt;/span&gt;(&lt;span style="color:#2b91af;"&gt;SPEventReceiverInstallerTypeHelper&lt;/span&gt;.
            CheckOption(eventReceiverInstallerType, 
            &lt;span style="color:#2b91af;"&gt;SPEventReceiverInstallerType&lt;/span&gt;.ItemCheckingIn))
        {
            &lt;span style="color:green;"&gt;// add ItemCheckingIn event handler
            &lt;/span&gt;receiverDefinition = contentType.EventReceivers.Add();
            receiverDefinition.Name = receiverName;
            receiverDefinition.Type = 
                &lt;span style="color:#2b91af;"&gt;SPEventReceiverType&lt;/span&gt;.ItemCheckingIn;
            receiverDefinition.Assembly = assemblyFullName;
            receiverDefinition.Class = className;
            receiverDefinition.SequenceNumber = sequenceNumber;
            receiverDefinition.Update();
        }

        &lt;span style="color:green;"&gt;//ItemCheckedIn event handler
        &lt;/span&gt;&lt;span style="color:blue;"&gt;if &lt;/span&gt;(&lt;span style="color:#2b91af;"&gt;SPEventReceiverInstallerTypeHelper&lt;/span&gt;.CheckOption
            (eventReceiverInstallerType, 
            &lt;span style="color:#2b91af;"&gt;SPEventReceiverInstallerType&lt;/span&gt;.ItemCheckedIn))
        {
            &lt;span style="color:green;"&gt;// add ItemCheckedIn event handler
            &lt;/span&gt;receiverDefinition = contentType.EventReceivers.Add();
            receiverDefinition.Name = receiverName;
            receiverDefinition.Type = 
                &lt;span style="color:#2b91af;"&gt;SPEventReceiverType&lt;/span&gt;.ItemCheckedIn;
            receiverDefinition.Assembly = assemblyFullName;
            receiverDefinition.Class = className;
            receiverDefinition.SequenceNumber = sequenceNumber;
            receiverDefinition.Update();
        }

        &lt;span style="color:green;"&gt;//update content type - setting the updateChildren 
        //parameter to true will update list content types
        &lt;/span&gt;&lt;strong&gt;contentType.Update(&lt;span style="color:blue;"&gt;true&lt;/span&gt;);&lt;/strong&gt;
    }

    &lt;span style="color:gray;"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color:green;"&gt;Remove an event handler registration from a list.
    &lt;/span&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name=&amp;quot;list&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;SharePoint list&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;param name=&amp;quot;receiverClass&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;Event receiver class name&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
    &lt;/span&gt;&lt;span style="color:blue;"&gt;internal static void &lt;/span&gt;RemoveEventHandlers(
        &lt;span style="color:#2b91af;"&gt;SPContentType &lt;/span&gt;contentType, 
        &lt;span style="color:blue;"&gt;string &lt;/span&gt;receiverClass)
    {
        &lt;span style="color:#2b91af;"&gt;SPEventReceiverDefinition &lt;/span&gt;receiverDefinition = &lt;span style="color:blue;"&gt;null&lt;/span&gt;;

        &lt;span style="color:green;"&gt;// cycle through all the receiver definitions and 
        //delete the receiver with the supplied class name
        &lt;/span&gt;&lt;span style="color:blue;"&gt;for &lt;/span&gt;(&lt;span style="color:blue;"&gt;int &lt;/span&gt;i = contentType.EventReceivers.Count - 1;
            i &amp;gt;= 0; i--)
        {
            receiverDefinition = contentType.EventReceivers[i];
            &lt;span style="color:blue;"&gt;if &lt;/span&gt;(receiverDefinition.Class == receiverClass)
            {
                receiverDefinition.Delete();
            }
        }
    }
}&lt;/pre&gt;

&lt;p&gt;The statement that does the trick is &amp;quot;contentType.Update(&lt;span style="color:blue;"&gt;true&lt;/span&gt;);&amp;quot; in the end of the AddEventHandler method. Setting the updateChildren parameter of this method to true will update list content types.&lt;/p&gt;&lt;img src="http://blogit.create.pt/aggbug.aspx?PostID=1493" width="1" height="1"&gt;</content><author><name>misidoro</name><uri>http://blogit.create.pt/members/misidoro.aspx</uri></author><category term="Sharepoint 2007" scheme="http://blogit.create.pt/blogs/miguelisidoro/archive/tags/Sharepoint+2007/default.aspx" /><category term="WSS" scheme="http://blogit.create.pt/blogs/miguelisidoro/archive/tags/WSS/default.aspx" /></entry><entry><title>SharePoint 2007 - Checking if a Workflow Instance is Completed</title><link rel="alternate" type="text/html" href="http://blogit.create.pt/blogs/miguelisidoro/archive/2008/10/25/SharePoint-2007-_2D00_-Checking-if-a-Workflow-Instance-is-Completed.aspx" /><id>http://blogit.create.pt/blogs/miguelisidoro/archive/2008/10/25/SharePoint-2007-_2D00_-Checking-if-a-Workflow-Instance-is-Completed.aspx</id><published>2008-10-25T16:31:59Z</published><updated>2008-10-25T16:31:59Z</updated><content type="html">&lt;h5&gt;Introduction&lt;/h5&gt;  &lt;p&gt;This blog post will show you how to check if a certain workflow instance is completed in a SharePoint list. In this example, let's assume that the default &amp;quot;Documents&amp;quot; document library in a team site is configured with a Collect Feedback workflow and that a new instance is started every time a new document is added to the library. The workflow is configured with 2 reviewers. My purpose is to start a custom workflow (associated with a custom workflow) on each document every time all reviewers have reviewed them, i.e., every time a Collect Feedback workflow instance is completed.&lt;/p&gt;  &lt;h5&gt;Example&lt;/h5&gt;  &lt;p&gt;The following example shows how the previously described scenario can be implemented. One first note is that when a workflow instance gets completed on a list item (thus changing the workflow status of the item), the item is not updated. This means that the obvious solution that would be to have an event handler running on the document library to detect the completion of the workflow for each document can't be implemented. The following example uses an alternative approach that makes use of an event handler associated with the &amp;quot;Task&amp;quot; content type, that is used on workflow tasks lists. The event handler will run every time a task is updated and will get the task associated list item (the document) and start a custom workflow on the document when its Collect Feedback workflow instance gets completed. Let's take a look at the code:&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;summary&amp;gt;
/// &lt;/span&gt;&lt;span style="color:green;"&gt;Event handler associated with the &amp;quot;Task&amp;quot; content types.
&lt;/span&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;/summary&amp;gt;
&lt;/span&gt;&lt;span style="color:blue;"&gt;public class &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;WorkflowCompletionCheckerEventReceiver &lt;/span&gt;: SPItemEventReceiver
{
    &lt;span style="color:green;"&gt;//custom content type name
    &lt;/span&gt;&lt;span style="color:blue;"&gt;private const string &lt;/span&gt;CUSTOM_CONTENT_TYPE_NAME = 
        &lt;span style="color:#a31515;"&gt;&amp;quot;My Custom Content Type&amp;quot;&lt;/span&gt;;
    &lt;span style="color:green;"&gt;//task list workflow list id field
    &lt;/span&gt;&lt;span style="color:blue;"&gt;public const string &lt;/span&gt;TASK_LIST_WORKFLOW_LIST_ID_FIELD_NAME = 
        &lt;span style="color:#a31515;"&gt;&amp;quot;ows_WorkflowListId&amp;quot;&lt;/span&gt;;
    &lt;span style="color:green;"&gt;//task list workflow item id field
    &lt;/span&gt;&lt;span style="color:blue;"&gt;public const string &lt;/span&gt;TASK_LIST_WORKFLOW_ITEM_ID_FIELD_NAME = 
        &lt;span style="color:#a31515;"&gt;&amp;quot;ows_WorkflowItemId&amp;quot;&lt;/span&gt;;
    &lt;span style="color:green;"&gt;//collect feedback workflow id
    &lt;/span&gt;&lt;span style="color:blue;"&gt;public const string &lt;/span&gt;COLLECT_FEEDBACK_WORKFLOW_ID = 
        &lt;span style="color:#a31515;"&gt;&amp;quot;46c389a4-6e18-476c-aa17-289b0c79fb8f&amp;quot;&lt;/span&gt;;
    &lt;span style="color:green;"&gt;//custom workflow id
    &lt;/span&gt;&lt;span style="color:blue;"&gt;public const string &lt;/span&gt;CUSTOM_WORKFLOW_ID = 
        &lt;span style="color:#a31515;"&gt;&amp;quot;96be29b0-1be4-4b99-a703-656e5470962b&amp;quot;&lt;/span&gt;;

    &lt;span style="color:gray;"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color:green;"&gt;Event handler for item updated event.
    &lt;/span&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name=&amp;quot;properties&amp;quot;&amp;gt;&amp;lt;/param&amp;gt;
    &lt;/span&gt;&lt;span style="color:blue;"&gt;public override void &lt;/span&gt;ItemUpdated(SPItemEventProperties properties)
    {
        &lt;span style="color:green;"&gt;//start a custom workflow on a list item when a 
        //collect feedback workflow gets completed
        &lt;/span&gt;StartCustomWorkflowOnTaskItemCompletion(properties);
    }

    &lt;span style="color:gray;"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color:green;"&gt;Checks if the &amp;quot;Collect Feedback&amp;quot; workflow 
    &lt;/span&gt;&lt;span style="color:gray;"&gt;/// &lt;/span&gt;&lt;span style="color:green;"&gt;instance on an item is completed. This method checkes a 
    &lt;/span&gt;&lt;span style="color:gray;"&gt;/// &lt;/span&gt;&lt;span style="color:green;"&gt;workflow task and verifies if they have been created by a 
    &lt;/span&gt;&lt;span style="color:gray;"&gt;/// &lt;/span&gt;&lt;span style="color:green;"&gt;&amp;quot;Collect Feedback&amp;quot; workflow and if the associated item is of 
    &lt;/span&gt;&lt;span style="color:gray;"&gt;/// &lt;/span&gt;&lt;span style="color:green;"&gt;my custom content type. If yes, it verifies if the workflow has 
    &lt;/span&gt;&lt;span style="color:gray;"&gt;/// &lt;/span&gt;&lt;span style="color:green;"&gt;been completed and if complete, starts a custom workflow 
    &lt;/span&gt;&lt;span style="color:gray;"&gt;/// &lt;/span&gt;&lt;span style="color:green;"&gt;on the associated item.
    &lt;/span&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name=&amp;quot;properties&amp;quot;&amp;gt;&amp;lt;/param&amp;gt;
    &lt;/span&gt;&lt;span style="color:blue;"&gt;private void &lt;/span&gt;StartCustomWorkflowOnTaskItemCompletion
        (SPItemEventProperties properties)
    {
        
        &lt;span style="color:green;"&gt;//get the task item
        &lt;/span&gt;SPListItem listItem = properties.ListItem;
        &lt;span style="color:blue;"&gt;if &lt;/span&gt;(listItem != &lt;span style="color:blue;"&gt;null&lt;/span&gt;)
        {
            &lt;span style="color:green;"&gt;//get associated item id and associated list id

            //list id - ows_WorkflowListId field
            &lt;/span&gt;&lt;span style="color:blue;"&gt;object &lt;/span&gt;associatedWorkflowListId = 
                listItem[TASK_LIST_WORKFLOW_LIST_ID_FIELD_NAME];
            &lt;span style="color:green;"&gt;//item id - ows_WorkflowItemId field
            &lt;/span&gt;&lt;span style="color:blue;"&gt;object &lt;/span&gt;associatedWorkflowItemId = 
                listItem[TASK_LIST_WORKFLOW_ITEM_ID_FIELD_NAME];

            &lt;span style="color:green;"&gt;//get associated item
            &lt;/span&gt;&lt;span style="color:blue;"&gt;if &lt;/span&gt;(associatedWorkflowItemId != &lt;span style="color:blue;"&gt;null 
                &lt;/span&gt;&amp;amp;&amp;amp; associatedWorkflowListId != &lt;span style="color:blue;"&gt;null&lt;/span&gt;)
            {
                &lt;span style="color:green;"&gt;//get task associated list item using 
                //its list id and item id
                &lt;/span&gt;SPListItem associatedListItem = listItem.Web.Lists
                 .GetList(&lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Guid&lt;/span&gt;(associatedWorkflowListId.ToString()), &lt;span style="color:blue;"&gt;false&lt;/span&gt;)
                 .GetItemById(&lt;span style="color:blue;"&gt;int&lt;/span&gt;.Parse(associatedWorkflowItemId.ToString()));

                &lt;span style="color:green;"&gt;//check if item is of my custom content type
                &lt;/span&gt;&lt;span style="color:blue;"&gt;if &lt;/span&gt;(associatedListItem.ContentType.Name
                    .Equals(CUSTOM_CONTENT_TYPE_NAME))
                {
                    &lt;span style="color:green;"&gt;//check if item has any workflow association
                    &lt;/span&gt;&lt;span style="color:blue;"&gt;if &lt;/span&gt;(associatedListItem.Workflows.Count &amp;gt; 0)
                    {
                        &lt;span style="color:green;"&gt;//iterate workflow associations and lookup 
                        //the collect feedback association
                        &lt;/span&gt;&lt;span style="color:blue;"&gt;foreach &lt;/span&gt;(SPWorkflow workflow &lt;span style="color:blue;"&gt;in 
                            &lt;/span&gt;associatedListItem.Workflows)
                        {
                            &lt;span style="color:#2b91af;"&gt;Guid &lt;/span&gt;collectFeedbackWorkflowId = 
                                &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Guid&lt;/span&gt;(COLLECT_FEEDBACK_WORKFLOW_ID);
                            &lt;span style="color:green;"&gt;//check if collect feedback workflow 
                            //instance is completed
                            &lt;/span&gt;&lt;span style="color:blue;"&gt;if &lt;/span&gt;(workflow.ParentAssociation.BaseId 
                                == collectFeedbackWorkflowId
                                &amp;amp;&amp;amp; workflow.InternalState 
                                == SPWorkflowState.Completed)
                            {
                                &lt;span style="color:green;"&gt;//if collect feedback workflow instance is 
                                //completed, start custom workflow that is 
                                //associated with the item
                                &lt;/span&gt;StartContentTypeWorkflow(associatedListItem, 
                                    CUSTOM_WORKFLOW_ID);
                            }
                        }
                    }
                }
            }
        }
    }

    &lt;span style="color:gray;"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color:green;"&gt;Starts a workflow associated to a content type programmatically.
    &lt;/span&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name=&amp;quot;properties&amp;quot;&amp;gt;&amp;lt;/param&amp;gt;
    &lt;/span&gt;&lt;span style="color:blue;"&gt;public static void &lt;/span&gt;StartContentTypeWorkflow(SPListItem listItem,
        &lt;span style="color:blue;"&gt;string &lt;/span&gt;workflowId)
    {
        &lt;span style="color:green;"&gt;//start specified workflow that is associated with the item
        &lt;/span&gt;SPWorkflowManager manager = listItem.Web.Site.WorkflowManager;
        &lt;span style="color:green;"&gt;//get list item content type
        &lt;/span&gt;SPContentType contentType = listItem.ContentType;
        &lt;span style="color:green;"&gt;//get list item workflow associations
        &lt;/span&gt;SPWorkflowAssociationCollection associationCollection = 
            contentType.WorkflowAssociations;
        &lt;span style="color:green;"&gt;//iterate all item workflow associations
        &lt;/span&gt;&lt;span style="color:blue;"&gt;foreach &lt;/span&gt;(SPWorkflowAssociation association &lt;span style="color:blue;"&gt;in &lt;/span&gt;associationCollection)
        {
            &lt;span style="color:#2b91af;"&gt;Guid &lt;/span&gt;workflowGuid = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Guid&lt;/span&gt;(workflowId);
            &lt;span style="color:green;"&gt;//check if current workflow association matches 
            //the specified workflow
            &lt;/span&gt;&lt;span style="color:blue;"&gt;if &lt;/span&gt;(association.BaseId == workflowGuid)
            {
                &lt;span style="color:blue;"&gt;string &lt;/span&gt;data = association.AssociationData;

                &lt;span style="color:green;"&gt;//start workflow
                &lt;/span&gt;SPWorkflow wf = manager.StartWorkflow(listItem, association, 
                    data, &lt;span style="color:blue;"&gt;false&lt;/span&gt;);
            }
        }
    }
}&lt;/pre&gt;

&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;In the previous example, the following actions are being performed:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;The ItemUpdated event in the event handler is being handled;&lt;/li&gt;

  &lt;li&gt;In the event handler, a reference to the task is obtained;&lt;/li&gt;

  &lt;li&gt;The associated list item is obtained using two columns of the task list item:&lt;/li&gt;

  &lt;ul&gt;
    &lt;li&gt;&amp;quot;ows_WorkflowListId&amp;quot; - holds the id of the list where the associated list item is created;&lt;/li&gt;

    &lt;li&gt;&amp;quot;ows_WorkflowItemId&amp;quot; - holds the id of the associated list item;&lt;/li&gt;
  &lt;/ul&gt;

  &lt;li&gt;The content type of the associated list item is checked for a match to my custom content type;&lt;/li&gt;

  &lt;li&gt;If there is a match, the list item workflow associations are checked for a match with the Collect Feedback workflow;&lt;/li&gt;

  &lt;li&gt;If there is a match and the workflow instance is completed, the custom workflow is started.&lt;/li&gt;
&lt;/ul&gt;&lt;img src="http://blogit.create.pt/aggbug.aspx?PostID=1426" width="1" height="1"&gt;</content><author><name>misidoro</name><uri>http://blogit.create.pt/members/misidoro.aspx</uri></author><category term="Sharepoint 2007" scheme="http://blogit.create.pt/blogs/miguelisidoro/archive/tags/Sharepoint+2007/default.aspx" /><category term=".NET" scheme="http://blogit.create.pt/blogs/miguelisidoro/archive/tags/.NET/default.aspx" /><category term="Windows Workflow" scheme="http://blogit.create.pt/blogs/miguelisidoro/archive/tags/Windows+Workflow/default.aspx" /></entry><entry><title>InfoPath 2007 - Conditional SUM</title><link rel="alternate" type="text/html" href="http://blogit.create.pt/blogs/miguelisidoro/archive/2008/08/02/InfoPath-2007-_2D00_-Conditional-SUM.aspx" /><id>http://blogit.create.pt/blogs/miguelisidoro/archive/2008/08/02/InfoPath-2007-_2D00_-Conditional-SUM.aspx</id><published>2008-08-02T19:52:08Z</published><updated>2008-08-02T19:52:08Z</updated><content type="html">&lt;p&gt;This blog post will show you how to create an expression box in an InfoPath 2007 form whose value is based on the result of an conditional sum. Consider the following InfoPath form template:&lt;/p&gt;  &lt;p&gt;&lt;img src="http://pic90.picturetrail.com/VOL2147/10903553/19399056/328442040.jpg" /&gt; &lt;/p&gt;  &lt;p&gt;The previous image shows a simple expense report. To support the introduction of the expense information, a Repeating Table control is used with three columns: &lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;strong&gt;Expense&lt;/strong&gt; - Expense Description. A simple Text Box control;&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Value&lt;/strong&gt; - Expense value. A simple Text Box control;&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Expense Type&lt;/strong&gt; - Drop-down List Box control that allows 4 expense types: Food, Land Travel, Air Travel and Parking.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Below the repeating table there are 5 expression boxes that show the total amount of the expense report and the total amount for each expense type. The total amount expression box is based on a simple sum expression and each of the expense type expression boxes are based on conditional sums filtered by the value of the expense type Drop-down List Box control. The expressions used for each expense type are the following:&lt;/p&gt;  &lt;div align="center"&gt;   &lt;table cellspacing="0" cellpadding="2" align="center"&gt;       &lt;tr&gt;         &lt;td&gt;&lt;strong&gt;Expression Box&lt;/strong&gt;&lt;/td&gt;          &lt;td&gt;&lt;strong&gt;Expression&lt;/strong&gt;&lt;/td&gt;          &lt;td&gt;&lt;strong&gt;XPath Expression&lt;/strong&gt;&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;Expense Total&lt;/td&gt;          &lt;td&gt;sum(expensevalue)&lt;/td&gt;          &lt;td&gt;sum(my:accounting/my:expensevalue)&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;Food Expense Total&lt;/td&gt;          &lt;td&gt;sum(accounting[expensetype = &amp;quot;Food&amp;quot;]/expensevalue)&lt;/td&gt;          &lt;td&gt;sum(my:accounting[my:expensetype = &amp;quot;Food&amp;quot;]/my:expensevalue)&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;Land Travel Expense Total&lt;/td&gt;          &lt;td&gt;sum(accounting[expensetype = &amp;quot;Land Travel&amp;quot;]/expensevalue)&lt;/td&gt;          &lt;td&gt;sum(my:accounting[my:expensetype = &amp;quot;Land Travel&amp;quot;]/my:expensevalue)&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;Air Travel Expense Total&lt;/td&gt;          &lt;td&gt;sum(accounting[expensetype = &amp;quot;Air Travel&amp;quot;]/expensevalue)&lt;/td&gt;          &lt;td&gt;sum(my:accounting[my:expensetype = &amp;quot;Air Travel&amp;quot;]/my:expensevalue)&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;Parking Expense Total&lt;/td&gt;          &lt;td&gt;sum(accounting[expensetype = &amp;quot;Parking&amp;quot;]/expensevalue)&lt;/td&gt;          &lt;td&gt;sum(my:accounting[my:expensetype = &amp;quot;Parking&amp;quot;]/my:expensevalue)&lt;/td&gt;       &lt;/tr&gt;     &lt;/table&gt; &lt;/div&gt;  &lt;p&gt;As the previous table shows, the conditional sum expressions for each expense type are relatively simple and pretty straightforward for those who are familiarized with XPath, since XPath syntax is used for each expression. This comes as no surprise since the underlying data of the InfoPath form is stored in XML. The following image shows an expense report example filled with some sample values:&lt;/p&gt;  &lt;p&gt;&lt;img src="http://pic90.picturetrail.com/VOL2147/10903553/19399056/328442036.jpg" /&gt;&lt;/p&gt;&lt;img src="http://blogit.create.pt/aggbug.aspx?PostID=758" width="1" height="1"&gt;</content><author><name>misidoro</name><uri>http://blogit.create.pt/members/misidoro.aspx</uri></author><category term="InfoPath 2007" scheme="http://blogit.create.pt/blogs/miguelisidoro/archive/tags/InfoPath+2007/default.aspx" /></entry><entry><title>SharePoint 2007 - New instances of this workflow template are currently disallowed</title><link rel="alternate" type="text/html" href="http://blogit.create.pt/blogs/miguelisidoro/archive/2008/07/12/SharePoint-2007-_2D00_-New-instances-of-this-workflow-template-are-currently-disallowed.aspx" /><id>http://blogit.create.pt/blogs/miguelisidoro/archive/2008/07/12/SharePoint-2007-_2D00_-New-instances-of-this-workflow-template-are-currently-disallowed.aspx</id><published>2008-07-12T15:28:45Z</published><updated>2008-07-12T15:28:45Z</updated><content type="html">&lt;p&gt;When creating a new custom workflow project using Visual Studio 2008, a strong key file (.snk) file is automatically included in the project to sign the workflow assembly. A few days ago, I started developing a SharePoint 2007 Sequential Workflow project. After finishing developing the workflow, I deployed it and started testing it by associating the workflow to a content type (Site Settings &amp;gt; Site Content Type Gallery &amp;gt; Site Content Type &amp;gt; Workflow settings). I then noticed that the strong key file that was being used to sign the workflow assembly wasn't the one I usually use and modified the project settings so that it started using it. After recompiling the project and redeploying the workflow, I started to get an error message: &amp;quot;New instances of this workflow template are currently disallowed&amp;quot;. The reason for this message to appear is that a new version version of the workflow had been deployed (same assembly with a different public key token due to the change in the strong key file used to sign the assembly). In these situations, the existing workflow associations made from older versions of the workflow are automatically set to &amp;quot;No New Instances&amp;quot;, meaning that new instances of the workflow for those workflow associations are not allowed. The image below shows the Remove Workflow page with my custom workflow association set to &amp;quot;No New Instances&amp;quot;. To access this page, go to Site Settings &amp;gt; Site Content Type Gallery &amp;gt; Site Content Type &amp;gt; Workflow settings &amp;gt; Remove Workflows if the workflow is associated with a content type.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;img src="http://pic90.picturetrail.com/VOL2147/10903553/19399056/325207336.jpg" /&gt; &lt;/p&gt;  &lt;p&gt;To solve the problem, all you have to do is to set the workflow association to &amp;quot;Allow&amp;quot; and new instances of the workflow can again be created.&lt;/p&gt;&lt;img src="http://blogit.create.pt/aggbug.aspx?PostID=571" width="1" height="1"&gt;</content><author><name>misidoro</name><uri>http://blogit.create.pt/members/misidoro.aspx</uri></author><category term="Sharepoint 2007" scheme="http://blogit.create.pt/blogs/miguelisidoro/archive/tags/Sharepoint+2007/default.aspx" /><category term="WSS" scheme="http://blogit.create.pt/blogs/miguelisidoro/archive/tags/WSS/default.aspx" /><category term="Windows Workflow" scheme="http://blogit.create.pt/blogs/miguelisidoro/archive/tags/Windows+Workflow/default.aspx" /></entry><entry><title>SharePoint 2007 - Start a Workflow Programmatically</title><link rel="alternate" type="text/html" href="http://blogit.create.pt/blogs/miguelisidoro/archive/2008/07/05/SharePoint-2007-_2D00_-Start-a-Workflow-Programmatically.aspx" /><id>http://blogit.create.pt/blogs/miguelisidoro/archive/2008/07/05/SharePoint-2007-_2D00_-Start-a-Workflow-Programmatically.aspx</id><published>2008-07-05T13:27:23Z</published><updated>2008-07-05T13:27:23Z</updated><content type="html">&lt;h5&gt;Introduction&lt;/h5&gt; &lt;p&gt;This blog post will show you how to start a workflow programmatically every time an item is updated in a SharePoint list. For those who don’t know, Windows Workflow Foundation (WF) is the new engine for building custom workflows (you can find more information about WF on the &lt;a href="http://msdn.microsoft.com/winfx/technologies/workflow/default.aspx"&gt;official web site&lt;/a&gt;). It was released as part of the .NET Framework 3.0 along with &lt;a href="http://msdn2.microsoft.com/en-us/netframework/aa663326.aspx"&gt;Windows Presentation Foundation (WPF)&lt;/a&gt; and &lt;a href="http://msdn2.microsoft.com/en-us/netframework/aa663324.aspx"&gt;Windows Communication Foundation (WCF)&lt;/a&gt;. In the SharePoint world, workflows can be associated both to a list and to a content type. Both options are valid and the choice for one or the other option depends on your needs:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;If you want to run a workflow in a list, independently of the content type of each list item, you should associate the workflow to a list. If you have more than one content type associated to the list, care should be taken in the workflow implementation since each content type can have different columns that may not be present in the other content types;  &lt;li&gt;If you want to run the workflow on all items of a specific content type, you should associate the workflow to a content type. The workflow will be associated to all list items from that content type in all lists across a site or the whole site collection (depending on the scope of the workflow, typically defined in its deployment feature) that are associated with the content type. &lt;/li&gt;&lt;/ul&gt; &lt;h5&gt;Example&lt;/h5&gt; &lt;p&gt;The following example shows how both options can be addressed. This example uses an event handler and starts a workflow every time an item is updated in a SharePoint list.&lt;/p&gt;&lt;pre class="code"&gt;&amp;nbsp;&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;public class &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;ProgrammaticWorkflowInitiationEventReceiver &lt;/span&gt;: SPItemEventReceiver
{
    &lt;span style="color:gray;"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color:green;"&gt;Event handler for item updated event.
    &lt;/span&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name="properties"&amp;gt;&amp;lt;/param&amp;gt;
    &lt;/span&gt;&lt;span style="color:blue;"&gt;public override void &lt;/span&gt;ItemUpdated(SPItemEventProperties properties)
    {
        &lt;span style="color:green;"&gt;//use this method if the workflow is associated to a list
        &lt;/span&gt;StartListWorkflow(properties);

        &lt;span style="color:green;"&gt;//use this method if the workflow is associated to a content type
        &lt;/span&gt;StartContentTypeWorkflow(properties);
    }

    &lt;span style="color:gray;"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color:green;"&gt;Starts a workflow associated to a list programmatically.
    &lt;/span&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name="properties"&amp;gt;&amp;lt;/param&amp;gt;
    &lt;/span&gt;&lt;span style="color:blue;"&gt;private void &lt;/span&gt;StartListWorkflow(SPItemEventProperties properties)
    {
        &lt;span style="color:green;"&gt;//get list item from event handler properties
        &lt;/span&gt;SPListItem listItem = properties.ListItem;

        &lt;span style="color:blue;"&gt;using &lt;/span&gt;(SPWeb web = listItem.Web)
        {
            &lt;span style="color:blue;"&gt;using &lt;/span&gt;(SPSite site = web.Site)
            {
                &lt;span style="color:green;"&gt;//obtain an instance of SPWorkflowManager 
                //which will be later used to start the workflow
                &lt;/span&gt;SPWorkflowManager manager = site.WorkflowManager;
                &lt;span style="color:green;"&gt;//get item's parent list
                &lt;/span&gt;SPList parentList = listItem.ParentList;
                &lt;span style="color:green;"&gt;//get all workflows that are associated with the list
                &lt;/span&gt;SPWorkflowAssociationCollection associationCollection = 
                    parentList.WorkflowAssociations;
                &lt;span style="color:green;"&gt;//lookup and start the worflow
                &lt;/span&gt;LookupAndStartWorkflow(listItem, manager,
                    associationCollection, &lt;span style="color:#a31515;"&gt;"FDEDCC37-4D8A-44ba-8E22-57B2669A887C"&lt;/span&gt;);
            }
        }
    }

    &lt;span style="color:gray;"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color:green;"&gt;Starts a workflow associated to a content type programmatically.
    &lt;/span&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name="properties"&amp;gt;&amp;lt;/param&amp;gt;
    &lt;/span&gt;&lt;span style="color:blue;"&gt;private void &lt;/span&gt;StartContentTypeWorkflow(SPItemEventProperties properties)
    {
        &lt;span style="color:green;"&gt;//get list item from event handler properties
        &lt;/span&gt;SPListItem listItem = properties.ListItem;

        &lt;span style="color:blue;"&gt;using &lt;/span&gt;(SPWeb web = listItem.Web)
        {
            &lt;span style="color:blue;"&gt;using &lt;/span&gt;(SPSite site = web.Site)
            {
                &lt;span style="color:green;"&gt;//obtain an instance of SPWorkflowManager 
                //which will be later used to start the workflow
                &lt;/span&gt;SPWorkflowManager manager = site.WorkflowManager;
                &lt;span style="color:green;"&gt;//get item's content type
                &lt;/span&gt;SPContentType contentType = listItem.ContentType;
                &lt;span style="color:green;"&gt;//get all workflows that are associated with the content type
                &lt;/span&gt;SPWorkflowAssociationCollection associationCollection = 
                    contentType.WorkflowAssociations;
                &lt;span style="color:green;"&gt;//lookup and start the worflow
                &lt;/span&gt;LookupAndStartWorkflow(listItem, manager,
                    associationCollection, &lt;span style="color:#a31515;"&gt;"FDEDCC37-4D8A-44ba-8E22-57B2669A887C"&lt;/span&gt;);
            }
        }
    }

    &lt;span style="color:gray;"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color:green;"&gt;Lookup and start the workflow.
    &lt;/span&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name="listItem"&amp;gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;param name="manager"&amp;gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;param name="associationCollection"&amp;gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;param name="workflowId"&amp;gt;&amp;lt;/param&amp;gt;
    &lt;/span&gt;&lt;span style="color:blue;"&gt;private static void &lt;/span&gt;LookupAndStartWorkflow(SPListItem listItem, 
        SPWorkflowManager manager, 
        SPWorkflowAssociationCollection associationCollection, 
        &lt;span style="color:blue;"&gt;string &lt;/span&gt;workflowId)
    {
        &lt;span style="color:green;"&gt;//iterate workflow associations and lookup the workflow to be started
        &lt;/span&gt;&lt;span style="color:blue;"&gt;foreach &lt;/span&gt;(SPWorkflowAssociation association &lt;span style="color:blue;"&gt;in &lt;/span&gt;associationCollection)
        {
            &lt;span style="color:green;"&gt;//if the workflow association matches the workflow we are looking for,
            //get its association data and start the workflow
            &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Guid &lt;/span&gt;workflowGuid = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Guid&lt;/span&gt;(workflowId);
            &lt;span style="color:blue;"&gt;if &lt;/span&gt;(association.BaseId == workflowGuid)
            {
                &lt;span style="color:green;"&gt;//get workflow association data
                &lt;/span&gt;&lt;span style="color:blue;"&gt;string &lt;/span&gt;data = association.AssociationData;

                &lt;span style="color:green;"&gt;//start workflow
                &lt;/span&gt;SPWorkflow wf = manager.StartWorkflow(listItem, association, data);
            }
        }
    }
}&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;In the previous example, the following actions are being performed:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The ItemUpdated event in the event handler is being handled. For demonstration purposes, I am assuming that two workflow associations were created, one to a list and another to a content type; 
&lt;li&gt;A call is made to the &lt;em&gt;StartListWorkflow&lt;/em&gt; method, which starts the workflow associated with a list; 
&lt;li&gt;A call is made to the &lt;em&gt;StartContentTypeWorkflow&lt;/em&gt; method, which starts the workflow associated with a content type. &lt;/li&gt;&lt;/ul&gt;&lt;img src="http://blogit.create.pt/aggbug.aspx?PostID=567" width="1" height="1"&gt;</content><author><name>misidoro</name><uri>http://blogit.create.pt/members/misidoro.aspx</uri></author><category term="Sharepoint 2007" scheme="http://blogit.create.pt/blogs/miguelisidoro/archive/tags/Sharepoint+2007/default.aspx" /><category term="WSS" scheme="http://blogit.create.pt/blogs/miguelisidoro/archive/tags/WSS/default.aspx" /><category term="Windows Workflow" scheme="http://blogit.create.pt/blogs/miguelisidoro/archive/tags/Windows+Workflow/default.aspx" /></entry><entry><title>SharePoint 2007 -  Getting an SPListItem by ID after a Search</title><link rel="alternate" type="text/html" href="http://blogit.create.pt/blogs/miguelisidoro/archive/2008/06/23/SharePoint-2007-_2D00_--Getting-an-SPListItem-by-ID-after-a-Search.aspx" /><id>http://blogit.create.pt/blogs/miguelisidoro/archive/2008/06/23/SharePoint-2007-_2D00_--Getting-an-SPListItem-by-ID-after-a-Search.aspx</id><published>2008-06-23T22:09:01Z</published><updated>2008-06-23T22:09:01Z</updated><content type="html">&lt;p&gt;After making a search to a SharePoint site, it isn't always easy to get a reference to each item returned in the search. This is because we don't know the Web and List where each item is located. The following example shows how this can be achieved:&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;class &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;SiteCollectionSearch
&lt;/span&gt;{
    &lt;span style="color:gray;"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color:green;"&gt;Search items by title
    &lt;/span&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name=&amp;quot;web&amp;quot;&amp;gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;
    &lt;/span&gt;&lt;span style="color:blue;"&gt;private static &lt;/span&gt;DataTable Search(SPWeb web)
    {
        &lt;span style="color:green;"&gt;//search items by title
        &lt;/span&gt;StringBuilder query = &lt;span style="color:blue;"&gt;new &lt;/span&gt;StringBuilder();
        query.Append(&lt;span style="color:#a31515;"&gt;&amp;quot;&amp;lt;Where&amp;gt;&amp;quot;&lt;/span&gt;);
        query.Append(&lt;span style="color:#a31515;"&gt;&amp;quot;&amp;lt;Contains&amp;gt;&amp;quot;&lt;/span&gt;);
        query.Append(&lt;span style="color:#a31515;"&gt;&amp;quot;&amp;lt;FieldRef Name='Title' /&amp;gt;&amp;quot;&lt;/span&gt;);
        query.Append(&lt;span style="color:#a31515;"&gt;&amp;quot;&amp;lt;Value Type='Text'&amp;gt;SharePoint&amp;lt;/Value&amp;gt;&amp;quot;&lt;/span&gt;);
        query.Append(&lt;span style="color:#a31515;"&gt;&amp;quot;&amp;lt;/Contains&amp;gt;&amp;quot;&lt;/span&gt;);
        query.Append(&lt;span style="color:#a31515;"&gt;&amp;quot;&amp;lt;/Where&amp;gt;&amp;quot;&lt;/span&gt;);
        query.RowLimit = 100;

        SPSiteDataQuery query = &lt;span style="color:blue;"&gt;new &lt;/span&gt;SPSiteDataQuery();
        query.Webs = &lt;span style="color:#a31515;"&gt;&amp;quot;&amp;lt;Webs Scope='SiteCollection' /&amp;gt;&amp;quot;&lt;/span&gt;;
        spQuery.Query = query.ToString();

        &lt;span style="color:green;"&gt;//perform the search
        &lt;/span&gt;DataTable searchResults = web.GetSiteData(query);

        &lt;span style="color:green;"&gt;//return results - since ViewFields property is not specified in
        //the query, WebId, ListId and Item Id are automatically returned
        &lt;/span&gt;&lt;span style="color:blue;"&gt;return &lt;/span&gt;searchResults;
    }

    &lt;span style="color:gray;"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color:green;"&gt;After a search, obtains each item by its Id.
    &lt;/span&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name=&amp;quot;list&amp;quot;&amp;gt;&amp;lt;/param&amp;gt;
    &lt;/span&gt;&lt;span style="color:blue;"&gt;private static void &lt;/span&gt;GetItemsByID()
    {
        SPSite site = &lt;span style="color:blue;"&gt;new &lt;/span&gt;SPSite(&lt;span style="color:#a31515;"&gt;&amp;quot;http://portal&amp;quot;&lt;/span&gt;);
        &lt;span style="color:blue;"&gt;using &lt;/span&gt;(SPWeb web = site.OpenWeb())
        {
            &lt;span style="color:green;"&gt;//search documents by title
            &lt;/span&gt;&lt;span style="color:blue;"&gt;using &lt;/span&gt;(DataTable docs = Search(web))
            {
                &lt;span style="color:green;"&gt;//iterate results
                &lt;/span&gt;&lt;span style="color:blue;"&gt;foreach &lt;/span&gt;(DataRow row &lt;span style="color:blue;"&gt;in &lt;/span&gt;docs.Rows)
                {
                    &lt;span style="color:green;"&gt;//get webId of the current item
                    &lt;/span&gt;Guid webId = &lt;span style="color:blue;"&gt;new &lt;/span&gt;Guid(Convert.ToString(row[&lt;span style="color:#a31515;"&gt;&amp;quot;WebID&amp;quot;&lt;/span&gt;]));
                    &lt;span style="color:green;"&gt;//get listId of the current item
                    &lt;/span&gt;Guid listId = &lt;span style="color:blue;"&gt;new &lt;/span&gt;Guid(Convert.ToString(row[&lt;span style="color:#a31515;"&gt;&amp;quot;ListID&amp;quot;&lt;/span&gt;]));
                    &lt;span style="color:green;"&gt;//get id of the current item
                    &lt;/span&gt;&lt;span style="color:blue;"&gt;int &lt;/span&gt;itemId = Convert.ToString(row[&lt;span style="color:#a31515;"&gt;&amp;quot;ID&amp;quot;&lt;/span&gt;]);

                    &lt;span style="color:green;"&gt;//get the web where the item is located
                    &lt;/span&gt;&lt;span style="color:blue;"&gt;using &lt;/span&gt;(SPWeb itemWeb = site.AllWebs[webId])
                    {
                        &lt;span style="color:green;"&gt;//get list using the list id
                        &lt;/span&gt;SPList list = itemWeb.Lists[listId];

                        SPListItem listItem = &lt;span style="color:blue;"&gt;null&lt;/span&gt;;
                        &lt;span style="color:blue;"&gt;try
                        &lt;/span&gt;{
                            &lt;span style="color:green;"&gt;//get item using its id
                            &lt;/span&gt;listItem = list.Items[itemId];
                        }
                        &lt;span style="color:blue;"&gt;catch &lt;/span&gt;{ }
                        &lt;span style="color:blue;"&gt;if &lt;/span&gt;(listItem != &lt;span style="color:blue;"&gt;null&lt;/span&gt;)
                        {
                            &lt;span style="color:green;"&gt;//do something with the item. Example: 
                            //update the title
                            &lt;/span&gt;listItem[&lt;span style="color:#a31515;"&gt;&amp;quot;Title&amp;quot;&lt;/span&gt;] = listItem[&lt;span style="color:#a31515;"&gt;&amp;quot;Title&amp;quot;&lt;/span&gt;] 
                                + &lt;span style="color:#a31515;"&gt;&amp;quot; Updated&amp;quot;&lt;/span&gt;;
                            listItem.Update();
                        }
                    }
                }
            }
        }
    }
}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;In the previous example, the following actions are being performed:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;A search is performed to entire site collection for documents containing the word &amp;quot;SharePoint&amp;quot;. As a result of that search, a DataTable instance is returned containing the search results; &lt;/li&gt;

  &lt;li&gt;Each row of the search results is iterated. For each row, three important values are obtained: the item's ID, ListId and WebId. These are obtained automatically in the result of a SPSiteDataQuery when the ViewFields property is not set;&lt;/li&gt;

  &lt;li&gt;The SPWeb instance where the item is located is obtained using the previously obtained WebId;&lt;/li&gt;

  &lt;li&gt;The SPList instance where the item is located is obtained using the previously obtained ListId;&lt;/li&gt;

  &lt;li&gt;The SPListItem is obtained from the list using the item's ID;&lt;/li&gt;

  &lt;li&gt;Finally, something is done with the item. For example, updating its title.&lt;/li&gt;
&lt;/ul&gt;&lt;img src="http://blogit.create.pt/aggbug.aspx?PostID=561" width="1" height="1"&gt;</content><author><name>misidoro</name><uri>http://blogit.create.pt/members/misidoro.aspx</uri></author><category term="Sharepoint 2007" scheme="http://blogit.create.pt/blogs/miguelisidoro/archive/tags/Sharepoint+2007/default.aspx" /><category term="WSS" scheme="http://blogit.create.pt/blogs/miguelisidoro/archive/tags/WSS/default.aspx" /></entry><entry><title>SharePoint 2007 - &quot;Value does not fall within the expected range&quot; when updating an SPListItem in a Search</title><link rel="alternate" type="text/html" href="http://blogit.create.pt/blogs/miguelisidoro/archive/2008/06/07/SharePoint-2007-_2D00_-_2200_Value-does-not-fall-within-the-expected-range_2200_-when-updating-an-SPListItem-in-a-Search.aspx" /><id>http://blogit.create.pt/blogs/miguelisidoro/archive/2008/06/07/SharePoint-2007-_2D00_-_2200_Value-does-not-fall-within-the-expected-range_2200_-when-updating-an-SPListItem-in-a-Search.aspx</id><published>2008-06-07T15:32:00Z</published><updated>2008-06-07T15:32:00Z</updated><content type="html">&lt;p&gt;A very common error message that appears when developing in the SharePoint platform is &amp;quot;Value does not all within the expected range&amp;quot; when trying to update an SPListItem that is the result of a query to a SharePoint list. Let&amp;#39;s look at the following example:&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;class &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;SearchListItem&lt;br /&gt;&lt;/span&gt;{&lt;br /&gt;    &lt;span style="color:gray;"&gt;/// &amp;lt;summary&amp;gt;&lt;br /&gt;    /// &lt;/span&gt;&lt;span style="color:green;"&gt;Search document by title&lt;br /&gt;    &lt;/span&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;/summary&amp;gt;&lt;br /&gt;    /// &amp;lt;param name=&amp;quot;list&amp;quot;&amp;gt;&amp;lt;/param&amp;gt;&lt;br /&gt;    /// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;&lt;br /&gt;    &lt;/span&gt;&lt;span style="color:blue;"&gt;private static &lt;/span&gt;SPListItem SearchDocument(SPList list)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color:green;"&gt;//search document by title&lt;br /&gt;        &lt;/span&gt;StringBuilder query = &lt;span style="color:blue;"&gt;new &lt;/span&gt;StringBuilder();&lt;br /&gt;        query.Append(&lt;span style="color:#a31515;"&gt;&amp;quot;&amp;lt;Where&amp;gt;&amp;quot;&lt;/span&gt;);&lt;br /&gt;        query.Append(&lt;span style="color:#a31515;"&gt;&amp;quot;&amp;lt;Eq&amp;gt;&amp;quot;&lt;/span&gt;);&lt;br /&gt;        query.Append(&lt;span style="color:#a31515;"&gt;&amp;quot;&amp;lt;FieldRef Name=&amp;#39;Title&amp;#39; /&amp;gt;&amp;quot;&lt;/span&gt;);&lt;br /&gt;        query.Append(&lt;span style="color:#a31515;"&gt;&amp;quot;&amp;lt;Value Type=&amp;#39;Text&amp;#39;&amp;gt;My document&amp;lt;/Value&amp;gt;&amp;quot;&lt;/span&gt;);&lt;br /&gt;        query.Append(&lt;span style="color:#a31515;"&gt;&amp;quot;&amp;lt;/Eq&amp;gt;&amp;quot;&lt;/span&gt;);&lt;br /&gt;        query.Append(&lt;span style="color:#a31515;"&gt;&amp;quot;&amp;lt;/Where&amp;gt;&amp;quot;&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;        SPView queryView = list.Views[&lt;span style="color:#a31515;"&gt;&amp;quot;All Documents&amp;quot;&lt;/span&gt;];&lt;br /&gt;        SPQuery spQuery = &lt;span style="color:blue;"&gt;new &lt;/span&gt;SPQuery(queryView);&lt;br /&gt;        spQuery.Query = query.ToString();&lt;br /&gt;        spQuery.ViewAttributes = &lt;span style="color:#a31515;"&gt;&amp;quot;Scope=\&amp;quot;RecursiveAll\&amp;quot;&amp;quot;&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;        SPListItemCollection items = list.GetItems(spQuery);&lt;br /&gt;        &lt;span style="color:blue;"&gt;if &lt;/span&gt;(items != &lt;span style="color:blue;"&gt;null &lt;/span&gt;&amp;amp;&amp;amp; items.Count &amp;gt; 0)&lt;br /&gt;            &lt;span style="color:blue;"&gt;return &lt;/span&gt;items[0];&lt;br /&gt;&lt;br /&gt;        &lt;span style="color:blue;"&gt;return null&lt;/span&gt;;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span style="color:gray;"&gt;/// &amp;lt;summary&amp;gt;&lt;br /&gt;    /// &lt;/span&gt;&lt;span style="color:green;"&gt;Update document.&lt;br /&gt;    &lt;/span&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;/summary&amp;gt;&lt;br /&gt;    /// &amp;lt;param name=&amp;quot;list&amp;quot;&amp;gt;&amp;lt;/param&amp;gt;&lt;br /&gt;    &lt;/span&gt;&lt;span style="color:blue;"&gt;private static void &lt;/span&gt;UpdateDocumentError(SPList list)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color:green;"&gt;//search document by title&lt;br /&gt;        &lt;/span&gt;SPListItem doc = SearchDocument(list);&lt;br /&gt;        &lt;span style="color:green;"&gt;//update item in list&lt;br /&gt;        &lt;/span&gt;doc[&lt;span style="color:#a31515;"&gt;&amp;quot;Title&amp;quot;&lt;/span&gt;] = &lt;span style="color:#a31515;"&gt;&amp;quot;My document modified&amp;quot;&lt;/span&gt;;&lt;br /&gt;        doc.Update(); &lt;span style="color:green;"&gt;//error &amp;quot;Value does not fall &lt;br /&gt;        //within the expected range&amp;quot; is thrown&lt;/span&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;pre class="code"&gt;&lt;span style="color:green;"&gt;    &lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;    &lt;span style="color:gray;"&gt;/// &amp;lt;summary&amp;gt;&lt;br /&gt;    /// &lt;/span&gt;&lt;span style="color:green;"&gt;Update document.&lt;br /&gt;    &lt;/span&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;/summary&amp;gt;&lt;br /&gt;    /// &amp;lt;param name=&amp;quot;list&amp;quot;&amp;gt;&amp;lt;/param&amp;gt;&lt;br /&gt;    &lt;/span&gt;&lt;span style="color:blue;"&gt;private static void &lt;/span&gt;UpdateDocumentSucess(SPList list)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color:green;"&gt;//search document by title&lt;br /&gt;        &lt;/span&gt;SPListItem doc = SearchDocument(list);&lt;br /&gt;        &lt;span style="color:green;"&gt;//get SPListItem directly from list&lt;br /&gt;        &lt;/span&gt;&lt;strong&gt;SPListItem item = doc.ParentList.GetItemById(doc.ID);&lt;/strong&gt;&lt;br /&gt;        &lt;span style="color:green;"&gt;//update item in list&lt;br /&gt;        &lt;/span&gt;item[&lt;span style="color:#a31515;"&gt;&amp;quot;Title&amp;quot;&lt;/span&gt;] = &lt;span style="color:#a31515;"&gt;&amp;quot;My document modified&amp;quot;&lt;/span&gt;;&lt;br /&gt;        item.Update(); &lt;span style="color:green;"&gt;//item updated sucessfully&lt;br /&gt;    &lt;/span&gt;}&lt;br /&gt;}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;In the previous example, the following actions are being performed:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;A search is performed within a list for a document named &amp;quot;My Document&amp;quot;. As a result of that search, a SPListItem instance is returned containing the document information; &lt;/li&gt;

  &lt;li&gt;In the &amp;quot;UpdateDocumentError&amp;quot; method, after the search is performed, the returned item is modified and the list is updated. This action will cause the exception &amp;quot;Value does not fall within the expected range&amp;quot; to be raised; &lt;/li&gt;

  &lt;li&gt;In the &amp;quot;UpdateDocumentSucess&amp;quot; method, after the search is performed, we obtain the item directly from the list using the ID of the SPListItem returned from the search (the line &lt;strong&gt;&amp;quot;SPListItem item = doc.ParentList.GetItemById(doc.ID);&amp;quot;&lt;/strong&gt; was added, returning a new SPListItem instance). The new instance is then modified and used to update the item in the list. This way, the item is sucessfully updated. &lt;/li&gt;
&lt;/ul&gt;&lt;img src="http://blogit.create.pt/aggbug.aspx?PostID=551" width="1" height="1"&gt;</content><author><name>misidoro</name><uri>http://blogit.create.pt/members/misidoro.aspx</uri></author><category term="Sharepoint 2007" scheme="http://blogit.create.pt/blogs/miguelisidoro/archive/tags/Sharepoint+2007/default.aspx" /><category term="WSS" scheme="http://blogit.create.pt/blogs/miguelisidoro/archive/tags/WSS/default.aspx" /></entry><entry><title>SharePoint 2007 - Save Site As Template in Publishing Sites</title><link rel="alternate" type="text/html" href="http://blogit.create.pt/blogs/miguelisidoro/archive/2008/05/16/SharePoint-2007-_2D00_-Save-Site-As-Template-in-Publishing-Sites.aspx" /><id>http://blogit.create.pt/blogs/miguelisidoro/archive/2008/05/16/SharePoint-2007-_2D00_-Save-Site-As-Template-in-Publishing-Sites.aspx</id><published>2008-05-16T10:10:28Z</published><updated>2008-05-16T10:10:28Z</updated><content type="html">&lt;p&gt;One situation that you may have experienced is the lack of the &amp;quot;Save site as template&amp;quot; link in the Site Settings page of a MOSS 2007 site even if you have administrative privileges on the site or site collection. This will happen if your site is a Publishing site (either a Publishing site, used primarily for public faced Internet web sites or a Collaboration Portal, used primarily for Intranet Portals). You can check if your site is a Publishing site by checking if you have the Office SharePoint Server Publishing Infrastructure feature activated if you are at the top level of your site collection or if Office SharePoint Server Publishing feature is activated if you are in a sub site. Microsoft has disabled the &amp;quot;Save site as template&amp;quot; for Publishing sites and it is not supported. If you still want to save your publishing site as a template, you can do it by appending&amp;#160; &amp;quot;/_layouts/savetmpl.aspx&amp;quot; to the URL of your site. If the URL of your site is &lt;/p&gt;  &lt;p&gt;&lt;a href="http://intranetportal/site"&gt;http://intranetportal/site&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;you just have to go to &lt;/p&gt;  &lt;p&gt;&lt;a href="http://intranet/teamsite/_layouts/savetmpl.aspx"&gt;http://intranetportal/site/_layouts/savetmpl.aspx&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;in order for you to save your site as a template. I have already successfully managed to save collaboration portal sites as templates but it might happen that you encounter some problems if you try to save a publishing site as template since this is not a supported procedure. For more information on this, please check &lt;a href="http://support.microsoft.com/kb/925189/en-us" target="_blank"&gt;this Microsoft Support article&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://blogit.create.pt/aggbug.aspx?PostID=531" width="1" height="1"&gt;</content><author><name>misidoro</name><uri>http://blogit.create.pt/members/misidoro.aspx</uri></author><category term="Sharepoint 2007" scheme="http://blogit.create.pt/blogs/miguelisidoro/archive/tags/Sharepoint+2007/default.aspx" /><category term="WSS" scheme="http://blogit.create.pt/blogs/miguelisidoro/archive/tags/WSS/default.aspx" /></entry><entry><title>Windows Workflow - Using the HandleExternalEventActivity</title><link rel="alternate" type="text/html" href="http://blogit.create.pt/blogs/miguelisidoro/archive/2008/04/16/Windows-Workflow-_2D00_-Using-the-HandleExternalEventActivity.aspx" /><id>http://blogit.create.pt/blogs/miguelisidoro/archive/2008/04/16/Windows-Workflow-_2D00_-Using-the-HandleExternalEventActivity.aspx</id><published>2008-04-16T15:09:54Z</published><updated>2008-04-16T15:09:54Z</updated><content type="html">&lt;h5&gt;Introduction&lt;/h5&gt;  &lt;p&gt;This is the first in a series of blog posts dedicated to Windows Workflow. For those who don&amp;#8217;t know, Windows Workflow Foundation (WF) is the new engine for building custom workflows (you can find more information about WF on the &lt;a href="http://msdn.microsoft.com/winfx/technologies/workflow/default.aspx"&gt;official web site&lt;/a&gt;). It was released as part of the .NET Framework 3.0 along with &lt;a href="http://msdn2.microsoft.com/en-us/netframework/aa663326.aspx"&gt;Windows Presentation Foundation (WPF)&lt;/a&gt; and &lt;a href="http://msdn2.microsoft.com/en-us/netframework/aa663324.aspx"&gt;Windows Communication Foundation (WCF)&lt;/a&gt;.&lt;/p&gt;  &lt;h5&gt;Local Service Communication&lt;/h5&gt;  &lt;p&gt;Workflows are not isolated entities and most of the times need to communicate with the outside world in order to perform some task. There are several ways of communicating with external entities/services, being one of them External Data Exchange and Local Service Communication. Local Service Communication basically allows workflows to communicate with an external service that resides within the workflow host. There are two main activities inside WF that allow communication between a workflow and an external service using Local Service Communication:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;strong&gt;CallExternalMethodActivity&lt;/strong&gt; &amp;#8211; Allows a workflow to call a method from an external service. The workflow and the host establish a contract (using an interface) that defines the way they communicate with each other. Basically the workflow calls a method of a service residing within the host that implements the contract interface. For more details about this activity, click &lt;a href="http://blogit.create.pt/blogs/tiagooliveira/archive/2008/04/16/Using-WF-CallExternalMethod-activity-in-Windows-Workflow.aspx" target="_blank"&gt;here&lt;/a&gt;. &lt;/li&gt;    &lt;li&gt;&lt;b&gt;HandleExternalEventActivity&lt;/b&gt; &amp;#8211; Besides allowing the workflow to call an external method, it is also possible for the host to send an event to the workflow in order for it to perform some task. This is achieved using the HandleExternalEventActivity that will put the workflow on an idle state until an external event is raised. Just as in CallExternalMethodActivity, the communication between the workflow and the external is based on a contract. &lt;/li&gt; &lt;/ul&gt;  &lt;h5&gt;&lt;/h5&gt;  &lt;h5&gt;Summary&lt;/h5&gt;  &lt;p&gt;To build a workflow that uses HandleExternalEventActivity to communicate with a service using Local Service Communication, you&amp;#8217;ll need to:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Define a contract (interface); &lt;/li&gt;    &lt;li&gt;Implement a service based on the defined contract; &lt;/li&gt;    &lt;li&gt;Develop a workflow that uses HandleExternalEventActivity; &lt;/li&gt;    &lt;li&gt;Develop a host for the workflow; &lt;/li&gt;    &lt;li&gt;Add the service to the workflow runtime in the host; &lt;/li&gt;    &lt;li&gt;Start the workflow and handle the workflow WorkflowIdled event in the host; &lt;/li&gt;    &lt;li&gt;Raise the event. &lt;/li&gt; &lt;/ul&gt;  &lt;h5&gt;&lt;/h5&gt;  &lt;h5&gt;Example&lt;/h5&gt;  &lt;p&gt;As already explained, the HandleExternalEventActivity allows communication between a workflow and an external service using Local Service Communication based on event notifications. Next, I will present a simple demo that will show a very basic usage of this activity. The demo is based on a simple Approval State Machine Workflow Console Application. The console application will ask the user if he/she wants to approve and based on the answer it will pass the corresponding answer to the workflow through the raise of an event. This is how the workflow looks like:&lt;/p&gt;  &lt;p&gt;&amp;#160; &lt;img src="http://pic90.picturetrail.com/VOL2147/10903553/19399056/312016167.jpg" /&gt; &lt;/p&gt;  &lt;p&gt;This workflow will basically handle the external event inside the &lt;i&gt;StartState&lt;/i&gt; activity and set the approved or rejected state according to the information supplied by the host in the event. The interface of the service is defined like this:&lt;/p&gt;  &lt;pre class="code"&gt;[&lt;span style="color:#2b91af;"&gt;ExternalDataExchange&lt;/span&gt;]
&lt;span style="color:blue;"&gt;public interface &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;IApprovalEventService
&lt;/span&gt;{
    &lt;span style="color:blue;"&gt;void &lt;/span&gt;RaiseSetStateEvent(&lt;span style="color:#2b91af;"&gt;Guid &lt;/span&gt;instanceId, &lt;span style="color:blue;"&gt;bool &lt;/span&gt;approve);

    &lt;span style="color:blue;"&gt;event &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;EventHandler&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;ApprovalExternalDataEventArgs&lt;/span&gt;&amp;gt; ExternalDataEvent;
    
}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;The interface uses the &lt;a href="http://msdn2.microsoft.com/en-us/library/system.workflow.activities.externaldataexchangeattribute.aspx" target="_blank"&gt;ExternalDataExchange&lt;/a&gt; attribute which allows the workflow to use it to communicate with the host using Local Service Communication. The interface defines the event, whose arguments are of type ApprovalExternalDataEventArgs, a type derived from ExternalEventArgs. It also defines a RaiseSetStateEvent method that will be used by the host to raise the event. This method defines an additional Boolean parameter named &lt;i&gt;approve&lt;/i&gt; in order to pass the approval information to the workflow. This is how the ApprovalExternalDataEventArgs class looks like:&lt;/p&gt;

&lt;pre class="code"&gt;[&lt;span style="color:#2b91af;"&gt;Serializable&lt;/span&gt;]
&lt;span style="color:blue;"&gt;public class &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;ApprovalExternalDataEventArgs &lt;/span&gt;: &lt;span style="color:#2b91af;"&gt;ExternalDataEventArgs
&lt;/span&gt;{
    &lt;span style="color:blue;"&gt;private bool &lt;/span&gt;_result;

    &lt;span style="color:blue;"&gt;public bool &lt;/span&gt;Result {
        &lt;span style="color:blue;"&gt;set &lt;/span&gt;{
            _result = &lt;span style="color:blue;"&gt;value&lt;/span&gt;; 
        }
        &lt;span style="color:blue;"&gt;get &lt;/span&gt;{
            &lt;span style="color:blue;"&gt;return &lt;/span&gt;_result;
        }
    }

    &lt;span style="color:blue;"&gt;public &lt;/span&gt;ApprovalExternalDataEventArgs(&lt;span style="color:#2b91af;"&gt;Guid &lt;/span&gt;instanceId, &lt;span style="color:blue;"&gt;bool &lt;/span&gt;approve)
        : &lt;span style="color:blue;"&gt;base&lt;/span&gt;(instanceId) {
        Result = approve;
    }
}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;In the constructor, a Boolean &lt;i&gt;approve&lt;/i&gt; parameter is used. This parameter is populated by the host when raising the event and is used to set the Result property that will be used later by the workflow. The other parameter used in the constructor is &lt;i&gt;instanceId&lt;/i&gt;, which is used to correlate the event with the right workflow instance.&lt;/p&gt;

&lt;p&gt;The HandleExternalEventActivity is defined inside the &lt;i&gt;StartState&lt;/i&gt; activity and is named &lt;i&gt;handleSetState&lt;/i&gt;. Here are the details of the &lt;i&gt;StartState&lt;/i&gt; activity:&lt;/p&gt;

&lt;p&gt;&lt;img src="http://pic90.picturetrail.com/VOL2147/10903553/19399056/312016166.jpg" /&gt; &lt;/p&gt;

&lt;p&gt;As shown in the image above, the external event is handled by the HandleExternalEventActivity &lt;i&gt;handleSetState.&lt;/i&gt; Then, based on the value that was supplied by the host, approval or rejected activities will be executed (in this case a simple message will be written to the application console). The properties for the HandleExternalEventActivity &lt;i&gt;handleSetState&lt;/i&gt; look like this:&lt;/p&gt;

&lt;p&gt;&lt;img src="http://pic90.picturetrail.com/VOL2147/10903553/19399056/313494752.jpg" /&gt; &lt;/p&gt;

&lt;p&gt;There are three properties worth mentioning here:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;b&gt;e&lt;/b&gt; &amp;#8211; It will hold the event arguments for the workflow instance. In this case it is set to &lt;i&gt;ExternalDataEvent&lt;/i&gt;, a public property in the workflow of type ApprovalExternalDataEventArgs. &lt;/li&gt;

  &lt;li&gt;&lt;b&gt;EventName&lt;/b&gt; &amp;#8211; name of the event that will be handled. Also set to &lt;i&gt;ExternalDataEvent.&lt;/i&gt;&lt;b&gt;&lt;/b&gt; &lt;/li&gt;

  &lt;li&gt;&lt;b&gt;InterfaceType&lt;/b&gt; &amp;#8211; name of the interface. Set to IApprovalEventService. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The IfElseActivity defined after the HandleExternalEventActivity will evaluate a code condition to determine whether to execute the Approve or Reject activities.&lt;/p&gt;

&lt;p&gt;&lt;img src="http://pic90.picturetrail.com/VOL2147/10903553/19399056/312025688.jpg" /&gt; &lt;/p&gt;

&lt;p&gt;The code condition is based on a CheckState method that will verify the Result property of the workflow ExternalDataEvent property.&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color:green;"&gt;// Code condition to evaluate whether to take the 1st branch, YesIfElseBranch
// Since it always returns true, the 1st branch is always taken.
&lt;/span&gt;&lt;span style="color:blue;"&gt;private void &lt;/span&gt;CheckState(&lt;span style="color:blue;"&gt;object &lt;/span&gt;sender, &lt;span style="color:#2b91af;"&gt;ConditionalEventArgs &lt;/span&gt;e) {
    e.Result = ExternalDataEvent.Result;
}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;The two remaining pieces of this demo are the service and the host console application. Here is the definition of the service:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;class &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;ApprovalEventService &lt;/span&gt;: &lt;span style="color:#2b91af;"&gt;IApprovalEventService
&lt;/span&gt;{
    &lt;span style="color:blue;"&gt;#region &lt;/span&gt;IApprovalEventService Members

    &lt;span style="color:blue;"&gt;public void &lt;/span&gt;RaiseSetStateEvent(&lt;span style="color:#2b91af;"&gt;Guid &lt;/span&gt;instanceId, &lt;span style="color:blue;"&gt;bool &lt;/span&gt;approve)
    {
        &lt;span style="color:green;"&gt;// create event
        &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;EventHandler&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;ApprovalExternalDataEventArgs&lt;/span&gt;&amp;gt; setStateEvent 
        = &lt;span style="color:blue;"&gt;this&lt;/span&gt;.ExternalDataEvent;

        &lt;span style="color:green;"&gt;// launch event
        &lt;/span&gt;&lt;span style="color:blue;"&gt;if &lt;/span&gt;(setStateEvent != &lt;span style="color:blue;"&gt;null&lt;/span&gt;)
            setStateEvent(&lt;span style="color:blue;"&gt;null&lt;/span&gt;, &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;ApprovalExternalDataEventArgs
                &lt;/span&gt;(instanceId, approve));
    }

    &lt;span style="color:blue;"&gt;public event &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;EventHandler&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;ApprovalExternalDataEventArgs&lt;/span&gt;&amp;gt; 
        ExternalDataEvent;
   

    &lt;span style="color:blue;"&gt;#endregion
&lt;/span&gt;}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;The console application code looks like this:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;private static &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;ApprovalEventService &lt;/span&gt;service;
&lt;span style="color:blue;"&gt;private static &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Guid &lt;/span&gt;instanceId; 

&lt;span style="color:gray;"&gt;/// &amp;lt;summary&amp;gt;
/// &lt;/span&gt;&lt;span style="color:green;"&gt;We've decorated the IEventService interface with the 
&lt;/span&gt;&lt;span style="color:gray;"&gt;/// &lt;/span&gt;&lt;span style="color:green;"&gt;ExternalDataExchangeAttribute.
&lt;/span&gt;&lt;span style="color:gray;"&gt;/// &lt;/span&gt;&lt;span style="color:green;"&gt;The event args class (ApprovalExternalDataEventArgs) 
&lt;/span&gt;&lt;span style="color:gray;"&gt;/// &lt;/span&gt;&lt;span style="color:green;"&gt;derives from ExternalDataEventArgs.
&lt;/span&gt;&lt;span style="color:gray;"&gt;/// &lt;/span&gt;&lt;span style="color:green;"&gt;The event args class (ApprovalExternalDataEventArgs) is serializable.
&lt;/span&gt;&lt;span style="color:gray;"&gt;/// &lt;/span&gt;&lt;span style="color:green;"&gt;ApprovalEventService implements IEventService.
&lt;/span&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;/summary&amp;gt;
/// &amp;lt;param name=&amp;quot;args&amp;quot;&amp;gt;&amp;lt;/param&amp;gt;
&lt;/span&gt;&lt;span style="color:blue;"&gt;static void &lt;/span&gt;Main(&lt;span style="color:blue;"&gt;string&lt;/span&gt;[] args)
{
    &lt;span style="color:blue;"&gt;using&lt;/span&gt;(&lt;span style="color:#2b91af;"&gt;WorkflowRuntime &lt;/span&gt;workflowRuntime = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;WorkflowRuntime&lt;/span&gt;())
    {
        &lt;span style="color:green;"&gt;//add ApprovalEventService service to the workflow runtime
        &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;AutoResetEvent &lt;/span&gt;waitHandle = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;AutoResetEvent&lt;/span&gt;(&lt;span style="color:blue;"&gt;false&lt;/span&gt;);
        &lt;span style="color:#2b91af;"&gt;ExternalDataExchangeService &lt;/span&gt;dataExchange = 
        &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;ExternalDataExchangeService&lt;/span&gt;();
        workflowRuntime.AddService(dataExchange);
        service = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;ApprovalEventService&lt;/span&gt;();
        dataExchange.AddService(service);
        
        workflowRuntime.WorkflowCompleted += 
        &lt;span style="color:blue;"&gt;delegate&lt;/span&gt;(&lt;span style="color:blue;"&gt;object &lt;/span&gt;sender, &lt;span style="color:#2b91af;"&gt;WorkflowCompletedEventArgs &lt;/span&gt;e) 
        {
            &lt;span style="color:green;"&gt;//display workflow completion message
            &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color:#a31515;"&gt;&amp;quot;Workflow completed.&amp;quot;&lt;/span&gt;);
            waitHandle.Set();
        };
        workflowRuntime.WorkflowTerminated += 
        &lt;span style="color:blue;"&gt;delegate&lt;/span&gt;(&lt;span style="color:blue;"&gt;object &lt;/span&gt;sender, &lt;span style="color:#2b91af;"&gt;WorkflowTerminatedEventArgs &lt;/span&gt;e)
        {
            &lt;span style="color:green;"&gt;//display error message if an exception is raised
            &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(e.Exception.Message);
            waitHandle.Set();
        };
        workflowRuntime.WorkflowIdled += 
        &lt;span style="color:blue;"&gt;delegate&lt;/span&gt;(&lt;span style="color:blue;"&gt;object &lt;/span&gt;sender, &lt;span style="color:#2b91af;"&gt;WorkflowEventArgs &lt;/span&gt;e)
        {
            &lt;span style="color:green;"&gt;//read the input from keyboard (yes/no) and raise 
            //the event passing the answer as a boolean parameter
            &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color:#a31515;"&gt;&amp;quot;Workflow idled.&amp;quot;&lt;/span&gt;);
            &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.Write(&lt;span style="color:#a31515;"&gt;&amp;quot;Do you want to approve? (Y/N) &amp;quot;&lt;/span&gt;);
            &lt;span style="color:blue;"&gt;string &lt;/span&gt;key = &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.ReadLine();
            &lt;span style="color:blue;"&gt;bool &lt;/span&gt;approved = key.ToLower() == &lt;span style="color:#a31515;"&gt;&amp;quot;y&amp;quot; &lt;/span&gt;? &lt;span style="color:blue;"&gt;true &lt;/span&gt;: &lt;span style="color:blue;"&gt;false&lt;/span&gt;;
            &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color:#a31515;"&gt;&amp;quot;Sending event to workflow.&amp;quot;&lt;/span&gt;);
            service.RaiseSetStateEvent(instanceId, approved);
        };

        &lt;span style="color:green;"&gt;//start workflow
        &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;WorkflowInstance &lt;/span&gt;instance = 
        workflowRuntime.CreateWorkflow(
        &lt;span style="color:blue;"&gt;typeof&lt;/span&gt;(StateMachineCommunicationDemo.&lt;span style="color:#2b91af;"&gt;SimpleStateMachine&lt;/span&gt;));
        instanceId = instance.InstanceId;
        &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color:#a31515;"&gt;&amp;quot;Starting workflow.&amp;quot;&lt;/span&gt;);
        instance.Start();

        &lt;span style="color:green;"&gt;//put workflow in an idle state
        &lt;/span&gt;waitHandle.WaitOne();

        &lt;span style="color:green;"&gt;//stop runtime
        &lt;/span&gt;workflowRuntime.StopRuntime();

        &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color:#a31515;"&gt;&amp;quot;Press any key.&amp;quot;&lt;/span&gt;);
        &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.Read();
    }
}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;In the code above, the following actions are performed:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;The service is added to the workflow runtime. In order for the service to be correctly added to runtime, two AddService methods must be executed and in the right order. First, an instance of ExternalDataExchangeService is added to the workflow runtime. Then, an instance of our service (ApprovalEventService) is added to the &lt;a href="http://msdn2.microsoft.com/en-us/library/system.workflow.activities.externaldataexchangeservice.aspx" target="_blank"&gt;ExternalDataExchangeService&lt;/a&gt; instance. &lt;/li&gt;

  &lt;li&gt;The workflow is started &lt;/li&gt;

  &lt;li&gt;The workflow is placed in an idle state &lt;/li&gt;

  &lt;li&gt;Several delegate functions are defined to handle workflow events. The most important one is the event handler for the WorkflowIdled event. The event handler will be trigger once the workflow is placed in an idle state. Then, the user will be asked the approval question and the event is raised which will cause the HandleExternalEventActivity in the workflow to be executed. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here is the application&amp;#8217;s output in case of approval:&lt;/p&gt;

&lt;p&gt;&lt;img src="http://pic90.picturetrail.com/VOL2147/10903553/19399056/313495367.jpg" /&gt; &lt;/p&gt;

&lt;p&gt;And in case of rejection:&lt;/p&gt;

&lt;p&gt;&lt;img src="http://pic90.picturetrail.com/VOL2147/10903553/19399056/313495369.jpg" /&gt;&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;Another related activity is the ListenActivity. For more information, please click &lt;a href="http://blogit.create.pt/blogs/tiagolucas/archive/2008/04/17/Windows-Workflow-_2D00_-Using-the-ListenActivity.aspx" target="_blank"&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://blogit.create.pt/aggbug.aspx?PostID=521" width="1" height="1"&gt;</content><author><name>misidoro</name><uri>http://blogit.create.pt/members/misidoro.aspx</uri></author><category term="Windows Workflow" scheme="http://blogit.create.pt/blogs/miguelisidoro/archive/tags/Windows+Workflow/default.aspx" /></entry><entry><title>TechDays 2008 – 3&#186; Dia</title><link rel="alternate" type="text/html" href="http://blogit.create.pt/blogs/miguelisidoro/archive/2008/03/17/TechDays-_1320_-3_BA00_-Dia.aspx" /><id>http://blogit.create.pt/blogs/miguelisidoro/archive/2008/03/17/TechDays-_1320_-3_BA00_-Dia.aspx</id><published>2008-03-17T21:51:00Z</published><updated>2008-03-17T21:51:00Z</updated><content type="html">Decorreu na passada semana entre os dias 12 e 14 de Mar&amp;ccedil;o a edi&amp;ccedil;&amp;atilde;o deste ano do &lt;a href="http://www.techdays.pt/" target="_blank"&gt;TechDays&lt;/a&gt;, o maior evento de tecnologia do pa&amp;iacute;s. Este evento juntou mais de 2000 profissionais na &amp;aacute;rea das TI, tendo sido dadas mais de 150 sess&amp;otilde;es t&amp;eacute;cnicas por 120 oradores, tendo sido claramente a maior edi&amp;ccedil;&amp;atilde;o deste evento. De seguida, deixo o meu testemunho relativamente &amp;agrave;s sess&amp;otilde;es a que tive oportunidade de assistir no 3&amp;ordm; dia.&lt;br /&gt;&lt;h4&gt;COL10 - Como Criar Solu&amp;ccedil;&amp;otilde;es/Aplica&amp;ccedil;&amp;otilde;es Utilizando o Open XML &lt;/h4&gt;&lt;p&gt;Oradores: Marcos Santos (Microsoft), Susana Guedes (Microsoft) e Bernardo Antunes (Devscope) &lt;/p&gt;&lt;p&gt;Esta sess&amp;atilde;o abordou o tema do Open XML e de como este pode ser usado no desenvolvimento de aplica&amp;ccedil;&amp;otilde;es. O Open XML pretende endere&amp;ccedil;ar os seguintes problemas: &lt;/p&gt;&lt;ul&gt;&lt;li&gt;A informa&amp;ccedil;&amp;atilde;o &amp;eacute; guardada em muitos formatos diferentes &lt;/li&gt;&lt;li&gt;Dif&amp;iacute;cil trocar e guardar a informa&amp;ccedil;&amp;atilde;o &lt;/li&gt;&lt;li&gt;Diferentes aplica&amp;ccedil;&amp;otilde;es usam formatos de documento de forma diferente &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;O objectivo passa por uniformizar o formato de documentos usado pelas aplica&amp;ccedil;&amp;otilde;es de forma a facilitar a interoperabilidade na troca de documentos entre organiza&amp;ccedil;&amp;otilde;es. O Open XML &amp;eacute; j&amp;aacute; o formato usado pelo Office 2007. Para quem n&amp;atilde;o sabe, se renomear um ficheiro .docx como exemplo para .zip pode ver a estrutura interna do ficheiro, basicamente um conjunto de ficheiros xml. &lt;/p&gt;&lt;p&gt;Mais informa&amp;ccedil;&amp;otilde;es e demos de utiliza&amp;ccedil;&amp;atilde;o do OpenXML em: &lt;a href="http://openxmldeveloper.org"&gt;http://openxmldeveloper.org&lt;/a&gt; e &lt;a href="http://www.openxmlcommunity.org/"&gt;http://www.openxmlcommunity.org/&lt;/a&gt;. &lt;/p&gt;&lt;h4&gt;ARC05 - Constru&amp;ccedil;&amp;atilde;o de Software+Services com a Plataforma Volta &lt;/h4&gt;&lt;p&gt;Oradores: Daniel Fisher e Michael Willers, DevCoach &lt;/p&gt;&lt;p&gt;O tema desta sess&amp;atilde;o foi muito interessante. &amp;quot;Volta&amp;quot; &amp;eacute; o nome de c&amp;oacute;digo de um projecto ainda em desenvolvimento por parte da Microsoft cujo objectivo &amp;eacute; o de uma forma transparente e sem qualquer esfor&amp;ccedil;o de desenvolvimento compilar c&amp;oacute;digo de assemblies .NET (em qualquer linguagem .NET compliant) em c&amp;oacute;digo Javascript compat&amp;iacute;vel &amp;quot;cross-browser&amp;quot;. Detalhando um pouco mais o conceito, a ideia &amp;eacute; desenvolver uma aplica&amp;ccedil;&amp;atilde;o (cliente, servi&amp;ccedil;os) em .NET e por meio de atributos definir se o c&amp;oacute;digo corre no cliente ou no servidor (basta incluir o atributo [&amp;quot;RunAtOrigin&amp;quot;]). O &amp;quot;Volta&amp;quot; vai gerar c&amp;oacute;digo javascript para a camada de cliente, web services para a camada de servidor e todo o c&amp;oacute;digo de &amp;quot;plumbing&amp;quot; (comunica&amp;ccedil;&amp;atilde;o, serializa&amp;ccedil;&amp;atilde;o, seguran&amp;ccedil;a, etc) entre as duas camadas. &lt;/p&gt;&lt;p&gt;Basicamente, a ideia &amp;eacute; desenvolver as aplica&amp;ccedil;&amp;otilde;es em .NET do lado do servidor na nossa linguagem preferida e como output obter uma aplica&amp;ccedil;&amp;atilde;o AJAX distribu&amp;iacute;da. &lt;/p&gt;&lt;p&gt;Mais informa&amp;ccedil;&amp;atilde;o pode ser obtida em &lt;a href="http://labs.live.com/volta/"&gt;http://labs.live.com/volta/&lt;/a&gt;. &lt;/p&gt;&lt;h4&gt;WEB05 - ASP.NET Futures - Dynamic Data Controls and Astoria Services &lt;/h4&gt;&lt;p&gt;Orador: Matt Gibbs, Microsoft (Blog: &lt;a href="http://blogs.msdn.com/mattgi"&gt;http://blogs.msdn.com/mattgi&lt;/a&gt;) &lt;/p&gt;&lt;p&gt;Esta sess&amp;atilde;o foi apresentada pelo Matt Gibbs que &amp;eacute; Development Manager da equipa de ASP.NET da Microsoft e abordou algumas das novidades que ir&amp;atilde;o estar presentes na pr&amp;oacute;xima vers&amp;atilde;o do ASP.NET. A sess&amp;atilde;o foi dividida em duas partes distintas: &lt;/p&gt;&lt;ul&gt;&lt;li&gt;Dynamic Data Controls &lt;/li&gt;&lt;li&gt;Astoria Web Data Services &lt;/li&gt;&lt;/ul&gt;&lt;h5&gt;&lt;strong&gt;Dynamic Data Controls &lt;/strong&gt;&lt;/h5&gt;&lt;p&gt;Os Dynamic Data Controls permitem a obten&amp;ccedil;&amp;atilde;o de forma din&amp;acirc;mica da estrutura da base de dados em tempo real e adaptar a sua apresenta&amp;ccedil;&amp;atilde;o automaticamente de acordo com a mesma. Estes controlos ir&amp;atilde;o estar integrados como extens&amp;otilde;es na pr&amp;oacute;xima vers&amp;atilde;o do ASP.NET e v&amp;ecirc;m alterar o ciclo de desenvolvimento de uma aplica&amp;ccedil;&amp;atilde;o ASP.NET &amp;quot;data-bounded&amp;quot;. Antes t&amp;iacute;nhamos: &lt;/p&gt;&lt;ul&gt;&lt;li&gt;Cria&amp;ccedil;&amp;atilde;o do modelo de BD &lt;/li&gt;&lt;li&gt;Cria&amp;ccedil;&amp;atilde;o das p&amp;aacute;ginas &lt;/li&gt;&lt;li&gt;Adi&amp;ccedil;&amp;atilde;o dos controlos &amp;agrave;s p&amp;aacute;ginas &lt;/li&gt;&lt;li&gt;Adi&amp;ccedil;&amp;atilde;o l&amp;oacute;gica de valida&amp;ccedil;&amp;atilde;o &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Com estes novos controlos e a com as novas templates de projectos existentes no Visual Studio 2008, teremos: &lt;/p&gt;&lt;ul&gt;&lt;li&gt;Cria&amp;ccedil;&amp;atilde;o do modelo de dados &lt;/li&gt;&lt;li&gt;Cria&amp;ccedil;&amp;atilde;o autom&amp;aacute;tica de um aplica&amp;ccedil;&amp;atilde;o com base no modelo de dados &lt;/li&gt;&lt;li&gt;Customiza&amp;ccedil;&amp;atilde;o da aplica&amp;ccedil;&amp;atilde;o (altera&amp;ccedil;&amp;atilde;o p&amp;aacute;ginas .aspx e controlos .ascx base) &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Mais informa&amp;ccedil;&amp;atilde;o sobre Dynamic Data Controls: &lt;a href="http://quickstarts.asp.net/Futures/dynamicdatacontrols/default.aspx"&gt;http://quickstarts.asp.net/Futures/dynamicdatacontrols/default.aspx&lt;/a&gt;. &lt;/p&gt;&lt;h5&gt;&lt;strong&gt;Astoria Web Data Services &lt;/strong&gt;&lt;/h5&gt;&lt;p&gt;Ainda em fase de prot&amp;oacute;tipo (ser&amp;aacute; designado por &amp;quot;ADO.NET Data Services&amp;quot;), a principal ideia &amp;eacute; simplificar o acesso a dados atrav&amp;eacute;s do consumo de servi&amp;ccedil;os com base em URIs (&lt;a href="http://quickstarts.asp.net/3-5-extensions/adonetdataservice/ConsumingDataService.aspx"&gt;http://quickstarts.asp.net/3-5-extensions/adonetdataservice/ConsumingDataService.aspx&lt;/a&gt;) e retornar os dados em formatos JSON (m&amp;eacute;todo de serializa&amp;ccedil;&amp;atilde;o mais simples para evitar o &amp;quot;overhead&amp;quot; do XML na troca de informa&amp;ccedil;&amp;atilde;o em web services - &lt;a href="http://www.json.org/"&gt;http://www.json.org/&lt;/a&gt; muito ligado ao Javascript e AJAX) ou XML. Os servi&amp;ccedil;os poder&amp;atilde;o ser consumidos tanto por AJAX ou por qualquer outro cliente non-AJAX (servi&amp;ccedil;o WCF, aplica&amp;ccedil;&amp;atilde;o web, aplica&amp;ccedil;&amp;atilde;o Windows-Forms, etc). &lt;/p&gt;&lt;p&gt;Mais informa&amp;ccedil;&amp;atilde;o sobre Astoria Web Data Services em &lt;a href="http://astoria.mslivelabs.com/"&gt;http://astoria.mslivelabs.com/&lt;/a&gt; e &lt;a href="http://quickstarts.asp.net/3-5-extensions/adonetdataservice/ADONETDataServicesFramework.aspx"&gt;http://quickstarts.asp.net/3-5-extensions/adonetdataservice/ADONETDataServicesFramework.aspx&lt;/a&gt;. &lt;/p&gt;&lt;h4&gt;VST03 - Hardcore Debuging e Profiling de Aplica&amp;ccedil;&amp;otilde;es .NET &lt;/h4&gt;&lt;p&gt;Oradores: Filipe Prezado e Jo&amp;atilde;o Loureiro, Microsoft &lt;/p&gt;&lt;p&gt;Foi mais a curiosidade que me levou a assistir a esta sess&amp;atilde;o, tendo-se revelado uma sess&amp;atilde;o bastante interessante, embora com um certo n&amp;iacute;vel de complexidade. Basicamente, foram apresentadas as t&amp;eacute;cnicas usadas pela equipa de suporte t&amp;eacute;cnico da Microsoft para resolu&amp;ccedil;&amp;atilde;o de problemas aplicacionais em produ&amp;ccedil;&amp;atilde;o, tanto em cen&amp;aacute;rios em que det&amp;ecirc;m o acesso remoto ao servidor como em casos em que tal n&amp;atilde;o sucede. Algumas das ferramentas apresentadas foram: Mdbg, WinDbg (a mais conhecida), SOSAssistant, Hawkeye. Com base nestas ferramentas, foram apresentadas t&amp;eacute;cnicas que permitiram a identifica&amp;ccedil;&amp;atilde;o de &amp;quot;memory leaks&amp;quot;, efectuar o memory dump para ficheiro (&amp;uacute;til em cen&amp;aacute;rios em que n&amp;atilde;o existe acesso remoto ao servidor) para posterior an&amp;aacute;lise, entre outras. Uma sess&amp;atilde;o diferente mas interessante. &lt;/p&gt;&lt;h4&gt;WEB04: MVC Framework on Future ASP.NET &lt;/h4&gt;&lt;p&gt;Orador: Matt Gibbs, Microsoft (Blog: &lt;a href="http://blogs.msdn.com/mattgi"&gt;http://blogs.msdn.com/mattgi&lt;/a&gt;) &lt;/p&gt;&lt;p&gt;Esta foi a segunda sess&amp;atilde;o apresentada pelo Matt Gibbs sobre a futura vers&amp;atilde;o do ASP.NET. Desta vez, foi apresentada a framework MVC para ASP.NET que &amp;eacute; a implementa&amp;ccedil;&amp;atilde;o da Microsoft desta &amp;quot;pattern&amp;quot;. Esta framework basicamente divide uma aplica&amp;ccedil;&amp;atilde;o em 3 &amp;quot;roles&amp;quot;: &lt;/p&gt;&lt;ul&gt;&lt;li&gt;Model (Modelo) &amp;ndash; representa os componentes da aplica&amp;ccedil;&amp;atilde;o que s&amp;atilde;o respons&amp;aacute;veis pela manuten&amp;ccedil;&amp;atilde;o do estado da aplica&amp;ccedil;&amp;atilde;o (os dados). O caso mais t&amp;iacute;pico &amp;eacute; a persist&amp;ecirc;ncia do estado numa base de dados (ex: uma classe Client que representa os dados de uma tabela Client numa base de dados SQL Server) &lt;/li&gt;&lt;li&gt;View (Vista) &amp;ndash; representa os componentes respons&amp;aacute;veis pela camada de apresenta&amp;ccedil;&amp;atilde;o da aplica&amp;ccedil;&amp;atilde;o &lt;/li&gt;&lt;li&gt;Controller (Controlador) &amp;ndash; representa os componentes respons&amp;aacute;veis pela interac&amp;ccedil;&amp;atilde;o com o utilizador, manipula&amp;ccedil;&amp;atilde;o do modelo e selec&amp;ccedil;&amp;atilde;o da vista a utilizar. &amp;Eacute; o controlador que fica encarregue pela interac&amp;ccedil;&amp;atilde;o com o utilizador e n&amp;atilde;o a vista, sendo esta apenas usada para apresenta&amp;ccedil;&amp;atilde;o da informa&amp;ccedil;&amp;atilde;o &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Um ponto importante a referir &amp;eacute; que o MVC n&amp;atilde;o vem substituir o modelo de desenvolvimento ASP.NET tradicional, apresentando-se antes como uma alternativa onde a ideia &amp;eacute; haver uma maior separa&amp;ccedil;&amp;atilde;o de responsabilidades entre os componentes da aplica&amp;ccedil;&amp;atilde;o. &lt;/p&gt;&lt;p&gt;As demos apresentadas n&amp;atilde;o foram t&amp;atilde;o bem conseguidas quanto estava &amp;agrave; espera, tendo ficado por explicar como exemplo a forma como s&amp;atilde;o obtidos ou como s&amp;atilde;o editados/inseridos dados numa base de dados (tipicamente a l&amp;oacute;gica ser&amp;aacute; colocada no componente &amp;quot;Model&amp;quot;). &lt;/p&gt;&lt;p&gt;Mais informa&amp;ccedil;&amp;atilde;o sobre o MVC em &lt;a href="http://weblogs.asp.net/scottgu/archive/2007/10/14/asp-net-mvc-framework.aspx"&gt;http://weblogs.asp.net/scottgu/archive/2007/10/14/asp-net-mvc-framework.aspx&lt;/a&gt; e &lt;a href="http://weblogs.asp.net/scottgu/archive/2007/11/13/asp-net-mvc-framework-part-1.aspx"&gt;http://weblogs.asp.net/scottgu/archive/2007/11/13/asp-net-mvc-framework-part-1.aspx&lt;/a&gt;. &lt;/p&gt;&lt;p&gt;Podem consultar as sess&amp;otilde;es do dia 1 &lt;a href="http://blogit.create.pt/blogs/miguelisidoro/archive/2008/03/17/TechDays-_1320_-1_BA00_-Dia.aspx"&gt;aqui&lt;/a&gt; e do dia 2 &lt;a href="http://blogit.create.pt/blogs/miguelisidoro/archive/2008/03/17/TechDays-_1320_-2_BA00_-Dia.aspx"&gt;aqui&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://blogit.create.pt/aggbug.aspx?PostID=491" width="1" height="1"&gt;</content><author><name>misidoro</name><uri>http://blogit.create.pt/members/misidoro.aspx</uri></author><category term="TechDays" scheme="http://blogit.create.pt/blogs/miguelisidoro/archive/tags/TechDays/default.aspx" /></entry><entry><title>TechDays 2008 – 2&#186; Dia</title><link rel="alternate" type="text/html" href="http://blogit.create.pt/blogs/miguelisidoro/archive/2008/03/17/TechDays-_1320_-2_BA00_-Dia.aspx" /><id>http://blogit.create.pt/blogs/miguelisidoro/archive/2008/03/17/TechDays-_1320_-2_BA00_-Dia.aspx</id><published>2008-03-17T21:49:00Z</published><updated>2008-03-17T21:49:00Z</updated><content type="html">Decorreu na passada semana entre os dias 12 e 14 de Mar&amp;ccedil;o a edi&amp;ccedil;&amp;atilde;o deste ano do &lt;a href="http://www.techdays.pt/" target="_blank"&gt;TechDays&lt;/a&gt;, o maior evento de tecnologia do pa&amp;iacute;s. Este evento juntou mais de 2000 profissionais na &amp;aacute;rea das TI, tendo sido dadas mais de 150 sess&amp;otilde;es t&amp;eacute;cnicas por 120 oradores, tendo sido claramente a maior edi&amp;ccedil;&amp;atilde;o deste evento. De seguida, deixo o meu testemunho relativamente &amp;agrave;s sess&amp;otilde;es a que tive oportunidade de assistir no 2&amp;ordm; dia.&lt;br /&gt;&lt;h4&gt;INT04 - Qual &amp;eacute; o Contexto desta Conversa&amp;ccedil;&amp;atilde;o? Activando Conversa&amp;ccedil;&amp;otilde;es Longas em Servi&amp;ccedil;os de Workflow. Servi&amp;ccedil;os &amp;quot;Dur&amp;aacute;veis&amp;quot; &lt;/h4&gt;&lt;p&gt;Orador: Jos&amp;eacute; Ant&amp;oacute;nio Silva, Microsoft &lt;/p&gt;&lt;p&gt;Tendo em considera&amp;ccedil;&amp;atilde;o a natureza dos workflows onde uma inst&amp;acirc;ncia de workflow pode estar activa durante um per&amp;iacute;odo de tempo longo (&amp;quot;long running instance&amp;quot;), &amp;eacute; necess&amp;aacute;rio desenvolver os servi&amp;ccedil;os WCF de forma a suportar este tipo de cliente. Esta sess&amp;atilde;o abordou o tema de servi&amp;ccedil;os &amp;quot;dur&amp;aacute;veis&amp;quot;. Estes s&amp;atilde;o um novo tipo de servi&amp;ccedil;o da .NET Framework 3.5 que permite simplificar a persist&amp;ecirc;ncia de estado numa &amp;quot;conversa&amp;ccedil;&amp;atilde;o&amp;quot; entre um servi&amp;ccedil;o WCF e um cliente (ex: um workflow). O modelo de persist&amp;ecirc;ncia do estado de um servi&amp;ccedil;o WCF &amp;eacute; em tudo id&amp;ecirc;ntico ao de WF, sendo poss&amp;iacute;vel guardar o estado em BD, files system, etc . De forma a tornar um servi&amp;ccedil;o WCF &amp;quot;dur&amp;aacute;vel&amp;quot; basta usar o prefixo &amp;quot;Durable&amp;quot; nos atributos da classe do servi&amp;ccedil;o. Exemplo: &lt;/p&gt;&lt;p&gt;&lt;span style="font-size:10pt;font-family:Verdana;"&gt;[Serializable] &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;&lt;span style="font-size:10pt;font-family:Verdana;"&gt;[DurableService]&lt;/span&gt;&lt;span style="font-size:12pt;font-family:Times New Roman;"&gt; &lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:10pt;font-family:Verdana;"&gt;public class TextComposer : ITextComposer&lt;/span&gt;&lt;span style="font-size:12pt;font-family:Times New Roman;"&gt; &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:10pt;font-family:Verdana;"&gt;{&lt;/span&gt;&lt;span style="font-size:12pt;font-family:Times New Roman;"&gt; &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:10pt;font-family:Verdana;"&gt;&amp;nbsp; &amp;nbsp; private string CurrentText ; &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:10pt;font-family:Verdana;"&gt;&lt;strong&gt;[DurableOperation]&lt;/strong&gt;&lt;/span&gt;&lt;span style="font-size:12pt;font-family:Times New Roman;"&gt;&lt;strong&gt; &lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:10pt;font-family:Verdana;"&gt;&amp;nbsp; &amp;nbsp; public string PowerOn(string text)&lt;/span&gt;&lt;span style="font-size:12pt;font-family:Times New Roman;"&gt; &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:10pt;font-family:Verdana;"&gt;&amp;nbsp; &amp;nbsp; {&lt;/span&gt;&lt;span style="font-size:12pt;font-family:Times New Roman;"&gt; &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:10pt;font-family:Verdana;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; CurrentText = text;&lt;/span&gt;&lt;span style="font-size:12pt;font-family:Times New Roman;"&gt; &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:10pt;font-family:Verdana;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return CurrentText;&lt;/span&gt;&lt;span style="font-size:12pt;font-family:Times New Roman;"&gt; &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:10pt;font-family:Verdana;"&gt;&amp;nbsp; &amp;nbsp; } &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:10pt;font-family:Verdana;"&gt;}&lt;/span&gt;&lt;span style="font-size:12pt;font-family:Times New Roman;"&gt; &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;Mais informa&amp;ccedil;&amp;atilde;o sobre &amp;quot;Durable Services&amp;quot; em &lt;a href="http://weblogs.asp.net/gsusx/archive/2007/06/14/orcas-durable-services.aspx"&gt;http://weblogs.asp.net/gsusx/archive/2007/06/14/orcas-durable-services.aspx&lt;/a&gt; (post antigo mas com uma boa explica&amp;ccedil;&amp;atilde;o) e em &lt;a href="http://www.microsoft.com/uk/msdn/nuggets/nugget/270/Durable-Services-with-WCF-V35.aspx"&gt;http://www.microsoft.com/uk/msdn/nuggets/nugget/270/Durable-Services-with-WCF-V35.aspx&lt;/a&gt; (screencast). &lt;/p&gt;&lt;p&gt;Algumas tools interessantes para WCF referidas durante a sess&amp;atilde;o: &lt;/p&gt;&lt;p&gt;&lt;strong&gt;Configuration Editor Tool&lt;/strong&gt; &amp;ndash; aplica&amp;ccedil;&amp;atilde;o que permite que permite a edi&amp;ccedil;&amp;atilde;o das configura&amp;ccedil;&amp;otilde;es de servi&amp;ccedil;os WCF com uma interface gr&amp;aacute;fica (Start&lt;span style="font-family:Wingdings;"&gt;&amp;agrave;&lt;/span&gt;Run&lt;span style="font-family:Wingdings;"&gt;&amp;agrave;&lt;/span&gt; SvcConfigEditor). Mais informa&amp;ccedil;&amp;atilde;o em &lt;a href="http://msdn2.microsoft.com/en-us/library/ms732009.aspx"&gt;http://msdn2.microsoft.com/en-us/library/ms732009.aspx&lt;/a&gt;. &lt;/p&gt;&lt;p&gt;&lt;strong&gt;WCF Test Client&lt;/strong&gt; &amp;ndash; aplica&amp;ccedil;&amp;atilde;o que permite efectuar testes &amp;quot;offline&amp;quot; sobre servi&amp;ccedil;os WCF (Start&lt;span style="font-family:Wingdings;"&gt;&amp;agrave;&lt;/span&gt;Run&lt;span style="font-family:Wingdings;"&gt;&amp;agrave;&lt;/span&gt; WcfTestClient). Mais informa&amp;ccedil;&amp;atilde;o em &lt;a href="http://msdn2.microsoft.com/en-us/library/bb552364.aspx"&gt;http://msdn2.microsoft.com/en-us/library/bb552364.aspx&lt;/a&gt;. &lt;/p&gt;&lt;p&gt;&lt;strong&gt;Service Trace Viewer Tool&lt;/strong&gt; &amp;ndash; aplica&amp;ccedil;&amp;atilde;o que permite a an&amp;aacute;lise dos logs de mensagens geradas pelo WCF (Start&lt;span style="font-family:Wingdings;"&gt;&amp;agrave;&lt;/span&gt;Run&lt;span style="font-family:Wingdings;"&gt;&amp;agrave;&lt;/span&gt; SvcTraceViewer). Mais informa&amp;ccedil;&amp;atilde;o em &lt;a href="http://msdn2.microsoft.com/en-us/library/ms732023.aspx"&gt;http://msdn2.microsoft.com/en-us/library/ms732023.aspx&lt;/a&gt;. &lt;/p&gt;&lt;h4&gt;ARC01 - Software + Services: The Convergence of SaaS, SOA and Web 2.0 &lt;/h4&gt;&lt;p&gt;Orador: Beat Schwegler, Microsoft&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Esta sess&amp;atilde;o retratou um tema muito em voga: o Software + Services. A sess&amp;atilde;o n&amp;atilde;o teve qualquer demo, tendo tido uma componente bastante te&amp;oacute;rica, tendo sido iniciada com a refer&amp;ecirc;ncia a tr&amp;ecirc;s conceitos importantes: SaaS (&lt;a href="http://msdn2.microsoft.com/en-us/architecture/aa699384.aspx"&gt;http://msdn2.microsoft.com/en-us/architecture/aa699384.aspx&lt;/a&gt;), SOA (&lt;a href="http://msdn2.microsoft.com/en-us/architecture/aa948857.aspx"&gt;http://msdn2.microsoft.com/en-us/architecture/aa948857.aspx&lt;/a&gt;) e Web 2.0 (&lt;a href="http://twopointouch.com/2006/08/17/10-definitions-of-web-20-and-their-shortcomings/"&gt;http://twopointouch.com/2006/08/17/10-definitions-of-web-20-and-their-shortcomings/&lt;/a&gt;). Foram referidos alguns exemplos de modelos de neg&amp;oacute;cio usados com S+S: Subscription/License Model, Advertisement Base Model (ex: Google). Foram dados ainda alguns exemplos de aplica&amp;ccedil;&amp;otilde;es S+S: Eve Online (&lt;a href="http://www.eve-online.com/"&gt;http://www.eve-online.com/&lt;/a&gt;), o Amazon S3 (&lt;a href="http://www.amazon.com/gp/browse.html?node=16427261"&gt;http://www.amazon.com/gp/browse.html?node=16427261&lt;/a&gt;) e a British Library. Por fim, foram ainda referidos alguns exemplos concretos de implementa&amp;ccedil;&amp;atilde;o do S+S pela Microsoft: &lt;/p&gt;&lt;ul&gt;&lt;li&gt;Finished Services &amp;ndash; Windows Live, Office Online &lt;/li&gt;&lt;li&gt;Attached Services &amp;ndash; XBOX Live &lt;/li&gt;&lt;li&gt;Building Blocks &amp;ndash; BizTalk Services &lt;/li&gt;&lt;/ul&gt;&lt;h4&gt;INT06: Viagem ao Centro da N&amp;uacute;vem &amp;ndash; O Internet Service Bus (ISB) e os BizTalk Services &lt;/h4&gt;&lt;p&gt;Orador: Jo&amp;atilde;o Pedro Martins a.k.a &amp;quot;Jota&amp;quot;, Create IT &lt;/p&gt;&lt;p&gt;A sess&amp;atilde;o come&amp;ccedil;ou de uma forma muito interessante com o Jota a &amp;quot;provocar&amp;quot; a audi&amp;ecirc;ncia com algumas ideias sobre a forma como ser&amp;aacute; o mundo das aplica&amp;ccedil;&amp;otilde;es no futuro como a transi&amp;ccedil;&amp;atilde;o de um mundo com &amp;quot;data centers&amp;quot; nas pr&amp;oacute;prias empresas para um em que o &amp;quot;hosting&amp;quot; &amp;eacute; feito por grandes empresas com super &amp;quot;data centers&amp;quot; dedicados a fazer o &amp;quot;hosting&amp;quot; de milhares de aplica&amp;ccedil;&amp;otilde;es. Foi uma forma interessante de cativar desde in&amp;iacute;cio a audi&amp;ecirc;ncia. Neste sentido, foram dadas algumas estat&amp;iacute;sticas interessantes como a previs&amp;atilde;o do aumento de n&amp;uacute;mero de servidores de hosting da Microsoft de 200000 actuais para 800000 em 2011, indo de encontro &amp;agrave; adop&amp;ccedil;&amp;atilde;o do conceito de Software como um servi&amp;ccedil;o (S+S) com as aplica&amp;ccedil;&amp;otilde;es a ser alojadas em &amp;quot;hosting&amp;quot; externo e serem expostas como servi&amp;ccedil;os. Os BizTalk Services, s&amp;atilde;o basicamente a vis&amp;atilde;o da Microsoft da forma como as aplica&amp;ccedil;&amp;otilde;es ir&amp;atilde;o comunica&amp;ccedil;&amp;atilde;o entre si no futuro, facilitando o desenvolvimento de aplica&amp;ccedil;&amp;otilde;es orientadas a servi&amp;ccedil;os (SOA). A ideia fundamental dos BizTalk Services &amp;eacute; a de permitir a comunica&amp;ccedil;&amp;atilde;o segura entre as aplica&amp;ccedil;&amp;otilde;es das organiza&amp;ccedil;&amp;otilde;es atrav&amp;eacute;s de firewalls.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;COL07 - Microsoft Search Server 2008 - Introdu&amp;ccedil;&amp;atilde;o e Apresenta&amp;ccedil;&amp;atilde;o de Novas Funcionalidades&lt;/strong&gt; &lt;/p&gt;&lt;p&gt;Oradores: Bruno Valente e Lu&amp;iacute;s Calado, Microsoft &lt;/p&gt;&lt;p&gt;O Microsoft Search Server 2008 (MSS 2008) &amp;eacute; a vers&amp;atilde;o 2 do j&amp;aacute; existente &amp;quot;SharePoint Server for Search&amp;quot;. As principais diferen&amp;ccedil;as de para a vers&amp;atilde;o anterior s&amp;atilde;o:&lt;span style="color:#17365d;"&gt;&lt;strong&gt; &lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Melhorias significativas na interface de administra&amp;ccedil;&amp;atilde;o &lt;/li&gt;&lt;li&gt;Pesquisa federada (a maior novidade) &lt;/li&gt;&lt;li&gt;Melhorias de performance e estabilidade &lt;/li&gt;&lt;li&gt;Pesquisa &amp;quot;cross-site&amp;quot; mesmo na vers&amp;atilde;o Express (ao contr&amp;aacute;rio do que acontecia antes) &lt;/li&gt;&lt;li&gt;&lt;div&gt;Melhorias nos relat&amp;oacute;rios &lt;/div&gt;&lt;ul&gt;&lt;li&gt;Dura&amp;ccedil;&amp;atilde;o &amp;uacute;ltima indexa&amp;ccedil;&amp;atilde;o e da actual &lt;/li&gt;&lt;li&gt;&amp;Uacute;ltima indexa&amp;ccedil;&amp;atilde;o completa, etc &lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;V&amp;atilde;o existir duas vers&amp;otilde;es do produto: &lt;/p&gt;&lt;ul&gt;&lt;li&gt;Search Server 2008 &amp;ndash; vers&amp;atilde;o paga que pode ser instalada num cen&amp;aacute;rio de farm. Os clientes MOSS n&amp;atilde;o ter&amp;atilde;o custos adicionais para fazer o upgrade para MSS 2008. &lt;/li&gt;&lt;li&gt;Search Server 2008 Express &amp;ndash; vers&amp;atilde;o gratuita que apenas pode ser instalada num &amp;uacute;nico servidor. &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;A principal novidade do produto &amp;eacute; a pesquisa federada. A ideia passa por permitir a pesquisa sobre outros motores de pesquisa ou aplica&amp;ccedil;&amp;otilde;es, integrada no SharePoint, sem ter que ter os conte&amp;uacute;dos indexados no &amp;iacute;ndice de SharePoint. Alguns dados sobre a pesquisa federada:&lt;br /&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;A &amp;uacute;nica desvantagem &amp;eacute; a inexist&amp;ecirc;ncia de &amp;quot;ranking&amp;quot; dos resultados de pesquisa pelo facto de n&amp;atilde;o estarem indexados. &lt;/li&gt;&lt;li&gt;Cada motor de pesquisa tem que ser configurado no SharePoint como uma localiza&amp;ccedil;&amp;atilde;o federada. &lt;/li&gt;&lt;li&gt;A pesquisa &amp;eacute; efectuada com base no standard OpenSearch (&lt;a href="http://www.opensearch.org/Home"&gt;http://www.opensearch.org/Home&lt;/a&gt;) onde a query de pesquisa &amp;eacute; enviada por URL. Ex: &lt;a href="http://search.live.com/result.aspx?q=%7bsearchTerms%7d"&gt;http://search.live.com/result.aspx?q=%7bsearchTerms%7d&lt;/a&gt; &lt;/li&gt;&lt;li&gt;Resultados de pesquisa devolvidos em XML &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Existem duas web parts &amp;quot;out-of-the-box&amp;quot; para pesquisa federada: &lt;/p&gt;&lt;ul&gt;&lt;li&gt;Federated Results Web Part: mostra todos os resultados de uma localiza&amp;ccedil;&amp;atilde;o federada &lt;/li&gt;&lt;li&gt;Top Federated Results Web Part: mostra os &amp;quot;top x&amp;quot; resultados de uma ou mais localiza&amp;ccedil;&amp;otilde;es federadas &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Podem consultar as sess&amp;otilde;es do dia 1 &lt;a href="http://blogit.create.pt/blogs/miguelisidoro/archive/2008/03/17/TechDays-_1320_-1_BA00_-Dia.aspx"&gt;aqui&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://blogit.create.pt/aggbug.aspx?PostID=489" width="1" height="1"&gt;</content><author><name>misidoro</name><uri>http://blogit.create.pt/members/misidoro.aspx</uri></author><category term="TechDays" scheme="http://blogit.create.pt/blogs/miguelisidoro/archive/tags/TechDays/default.aspx" /></entry><entry><title>TechDays 2008 – 1&#186; Dia</title><link rel="alternate" type="text/html" href="http://blogit.create.pt/blogs/miguelisidoro/archive/2008/03/17/TechDays-_1320_-1_BA00_-Dia.aspx" /><id>http://blogit.create.pt/blogs/miguelisidoro/archive/2008/03/17/TechDays-_1320_-1_BA00_-Dia.aspx</id><published>2008-03-17T21:46:00Z</published><updated>2008-03-17T21:46:00Z</updated><content type="html">Decorreu na passada semana entre os dias 12 e 14 de Mar&amp;ccedil;o a edi&amp;ccedil;&amp;atilde;o deste ano do &lt;a href="http://www.techdays.pt/" target="_blank"&gt;TechDays&lt;/a&gt;, o maior evento de tecnologia do pa&amp;iacute;s. Este evento juntou mais de 2000 profissionais na &amp;aacute;rea das TI, tendo sido dadas mais de 150 sess&amp;otilde;es t&amp;eacute;cnicas por 120 oradores, tendo sido claramente a maior edi&amp;ccedil;&amp;atilde;o deste evento. De seguida, deixo o meu testemunho relativamente &amp;agrave;s sess&amp;otilde;es a que tive oportunidade de assistir no 1&amp;ordm; dia.&lt;br /&gt;&lt;h4&gt;COL03 &amp;ndash; Arquitectura e Desenvolvimento de Aplica&amp;ccedil;&amp;otilde;es que Permitem Pesquisa com MOSS &lt;/h4&gt;&lt;p&gt;Orador: Beat Schwegler, Microsoft (Blog: &lt;a href="http://blogs.msdn.com/beatsch/"&gt;http://blogs.msdn.com/beatsch/&lt;/a&gt;) &lt;/p&gt;&lt;p&gt;Esta sess&amp;atilde;o foi dividida em duas partes: &lt;/p&gt;&lt;ul&gt;&lt;li&gt;Como tornar informa&amp;ccedil;&amp;atilde;o das aplica&amp;ccedil;&amp;otilde;es pesquis&amp;aacute;vel no MOSS &lt;/li&gt;&lt;li&gt;Como efectuar pesquisas no MOSS a partir de aplica&amp;ccedil;&amp;otilde;es e apresentar os resultados &lt;/li&gt;&lt;/ul&gt;&lt;h5&gt;Como tornar informa&amp;ccedil;&amp;atilde;o das aplica&amp;ccedil;&amp;otilde;es pesquis&amp;aacute;vel no MOSS &lt;/h5&gt;&lt;p&gt;Foi dada uma introdu&amp;ccedil;&amp;atilde;o sobre a arquitectura de pesquisa do MOSS e os seus componentes (Content Sources [File, BDs, Exchange,etc], Protocol Handlers [http, ftp, file, BDC, etc], IFilters, Metadata e permiss&amp;otilde;es). &lt;/p&gt;&lt;p&gt;De seguida, foram referidos os requisitos para tornar formatos de ficheiro propriet&amp;aacute;rios pesquis&amp;aacute;veis no MOSS, tendo que para tal ser instalado um iFilter de forma a que o motor de indexa&amp;ccedil;&amp;atilde;o do MOSS possa ler o conte&amp;uacute;do dos ficheiros e index&amp;aacute;-los. &lt;/p&gt;&lt;p&gt;Para tornar conte&amp;uacute;dos de aplica&amp;ccedil;&amp;otilde;es LOB pesquis&amp;aacute;veis, deve ser usado o BDC. Deve ser criado o ficheiro xml de meta dados (metadata.xml). No ficheiro de meta dados devem ser especificados: &lt;/p&gt;&lt;ul&gt;&lt;li&gt;Entidades &lt;/li&gt;&lt;li&gt;M&amp;eacute;todos - devem ser especificados m&amp;eacute;todos Finder e SpecificFinder de forma a que os dados possam ser pesquisados. &lt;/li&gt;&lt;/ul&gt;&lt;h5&gt;Como efectuar pesquisas no MOSS a partir de aplica&amp;ccedil;&amp;otilde;es e apresentar os resultados &lt;/h5&gt;&lt;p&gt;Podem ser usados 3 m&amp;eacute;todos: &lt;/p&gt;&lt;ul&gt;&lt;li&gt;URL Syntax for Search &amp;ndash; chamada a p&amp;aacute;gina de search da seguinte forma: &lt;a&gt;http://Server_Name/[sites/][Site_Name/]/results.aspx?k=Palavra&lt;/a&gt; &lt;/li&gt;&lt;li&gt;RSS &lt;/li&gt;&lt;li&gt;Query Web Service for Search &amp;ndash; utiliza&amp;ccedil;&amp;atilde;o do Web service &lt;a href="http://Server_Name/%5bsites/%5d%5bSite_Name/%5d_vti_bin/search.asmx"&gt;http://Server_Name/%5bsites/%5d%5bSite_Name/%5d_vti_bin/search.asmx&lt;/a&gt; - m&amp;eacute;todo mais poderoso. &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Informa&amp;ccedil;&amp;atilde;o adicional: &lt;a href="http://msdn2.microsoft.com/en-us/library/bb887531.aspx"&gt;http://msdn2.microsoft.com/en-us/library/bb887531.aspx&lt;/a&gt; &lt;/p&gt;&lt;h4&gt;ARC04 &amp;ndash; Database Design Patterns: Boas Pr&amp;aacute;ticas para os Modelos de Dados &lt;/h4&gt;&lt;p&gt;Orador: Stephen Forte, Corzen, Inc. (Blog: &lt;a href="http://www.stephenforte.net/"&gt;http://www.stephenforte.net/&lt;/a&gt;) &lt;/p&gt;&lt;p&gt;Esta sess&amp;atilde;o foi muito interessante, das mais interessantes a que assisti. O orador (americano) &amp;eacute; um comunicador nato, cativando desde o in&amp;iacute;cio a audi&amp;ecirc;ncia. Durante a sess&amp;atilde;o foram abordados dois t&amp;oacute;picos essenciais: &lt;/p&gt;&lt;ul&gt;&lt;li&gt;Data Model Patterns &lt;/li&gt;&lt;li&gt;Infrastructure Patterns &amp;ndash; Data Partitioning &lt;/li&gt;&lt;/ul&gt;&lt;h5&gt;&lt;strong&gt;Data Model Patterns &lt;/strong&gt;&lt;/h5&gt;&lt;p&gt;Existem 3 patterns: &lt;/p&gt;&lt;ul&gt;&lt;li&gt;Transactional Design Pattern &amp;ndash; este modelo deve ser usado para as bases de dados operacionais, com elevado n&amp;iacute;vel de transac&amp;ccedil;&amp;otilde;es (OLTP), tipicamente bases de dados de suporte ao neg&amp;oacute;cio. O modelo de dados deve ser definido para que a base de dados se encontre normalizada. N&amp;atilde;o devem ser usados &amp;iacute;ndices de forma a evitar perdas de performance nas opera&amp;ccedil;&amp;otilde;es de insert, delete e update. &lt;/li&gt;&lt;li&gt;Slowly Changing Dimensions Design Pattern (SCD)&amp;ndash; esta pattern deve ser usada para bases de dados de reporting e consulta de informa&amp;ccedil;&amp;atilde;o. O seu preenchimento &amp;eacute; feito a partir da BD OLTP, devendo a a estrutura da BD ser desnormalizada e as tabelas desenhadas de forma a agregar toda a informa&amp;ccedil;&amp;atilde;o que se pretenda consultar na mesma tabela de forma a simplificar as querys (evitando joins com outras tabelas) e desta forma conseguir-se querys mais r&amp;aacute;pidas. Com este modelo evita-se que as querys de report sejam efectuadas sobre a BD OLTP. Neste tipo de BDs, podem e devem ser usados &amp;iacute;ndices para acelerar as querys. &lt;/li&gt;&lt;li&gt;Data Warehouse Design Pattern &amp;ndash; este modelo &amp;eacute; uma extens&amp;atilde;o do anterior, tendo um pouco mais de estrutura (existem N tabelas de dimens&amp;atilde;o [Tempo, Produto, Sexo, etc] e uma tabela de Factos [com uma chave estrangeira para cada tabela de dimens&amp;otilde;es] onde s&amp;atilde;o guardados os dados a partir da BD OLTP). Este modelo deve ser usado em detrimento do SCD em BDs com volumes massivos de dados. &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Existem v&amp;aacute;rias formas para popular as BDs SCD ou DW: por T-SQL, DTS, SSIS, etc. &lt;/p&gt;&lt;p&gt;Foi dado um exemplo concreto da utiliza&amp;ccedil;&amp;atilde;o destes modelos: a Amazon.com usa uma BD OLTP para todas as ordens de compra e uma BD SCD para os cat&amp;aacute;logos de produtos. &lt;/p&gt;&lt;h5&gt;&lt;strong&gt;Infrastructure Patterns &amp;ndash; Data Partitioning &lt;/strong&gt;&lt;/h5&gt;&lt;p&gt;Os patterns seguintes devem ser usados quando se tiver um volume muito grande de informa&amp;ccedil;&amp;atilde;o e as querys &amp;agrave; BD come&amp;ccedil;arem a ficar lentas. &lt;/p&gt;&lt;p&gt;Existem 2 patterns: &lt;/p&gt;&lt;ul style="margin-left:72pt;"&gt;&lt;li&gt;Horizontal Partitioning &amp;ndash; consiste em dividir os dados em v&amp;aacute;rias tabelas com a mesma estrutura. Exemplos: dados anuais, dados semestrais, etc conforme o volume de dados. &lt;/li&gt;&lt;li&gt;Vertical Align &amp;ndash; consiste em dividir os dados em duas ou mais tabelas, mantendo o n&amp;uacute;mero de registos intacto. Numa tabela, s&amp;atilde;o guardados as colunas mais acedidas (ex: nome, email, etc), colocando-se na(s) restante(s) as colunas menos acedidas. &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Estas duas patterns podem ser usadas em conjunto. &lt;/p&gt;&lt;p&gt;O particionamento de dados pode tamb&amp;eacute;m ser feito, separando os dados em v&amp;aacute;rios discos, de forma a que se um disco ficar inoperacional, os outros continuam a funcionar. &lt;/p&gt;&lt;h4&gt;COL01 - Gest&amp;atilde;o de Conte&amp;uacute;dos e Usabilidade com Sharepoint (MOSS) &lt;/h4&gt;&lt;p&gt;Oradores: Carla Faria e Lu&amp;iacute;s Calado, Microsoft &lt;/p&gt;&lt;p&gt;Esta sess&amp;atilde;o foi composta por duas partes distintas, apresentadas por cada um dos oradores: &lt;/p&gt;&lt;ul&gt;&lt;li&gt;Acessibilidade na Web em geral - Carla Faria &lt;/li&gt;&lt;li&gt;Acessibilidade com SharePoint (MOSS) &amp;ndash; Lu&amp;iacute;s Calado &lt;/li&gt;&lt;/ul&gt;&lt;h5&gt;&lt;strong&gt;Acessibilidade na Web em geral &lt;/strong&gt;&lt;/h5&gt;&lt;p&gt;A Carla Faria &amp;eacute; uma especialista em acessibilidade na Web. De seguida, fica um resumo das &amp;quot;guidelines&amp;quot; de acessibilidade apresentadas na sess&amp;atilde;o: &lt;/p&gt;&lt;ul style="margin-left:37pt;"&gt;&lt;li&gt;Evitar p&amp;aacute;ginas muito extensas (dif&amp;iacute;ceis de ler) &lt;/li&gt;&lt;li&gt;Pesquisa deve constar em todas as p&amp;aacute;ginas dos sites &lt;/li&gt;&lt;li&gt;Testar os sites com m&amp;eacute;todos de navega&amp;ccedil;&amp;atilde;o alternativos. Exemplo: usar leitor de ecr&amp;atilde; e aferir a facilidade de navega&amp;ccedil;&amp;atilde;o pela informa&amp;ccedil;&amp;atilde;o no site &lt;/li&gt;&lt;li&gt;N&amp;atilde;o abrir links em novas janela por omiss&amp;atilde;o &lt;/li&gt;&lt;li&gt;Manter um layout consistente em todo o site (evitar diferen&amp;ccedil;as significativas de layout entre &amp;aacute;reas do site). Os links para servi&amp;ccedil;os devem estar sempre no mesmo local &lt;/li&gt;&lt;li&gt;N&amp;atilde;o colocar sons de fundo (ex: &lt;a href="http://www.superbock.pt/frameset.aspx?urlto=http%3A//www.superbock.pt/SuperMusic/sbsr14/%23"&gt;http://www.superbock.pt/frameset.aspx?urlto=http%3A//www.superbock.pt/SuperMusic/sbsr14/%23&lt;/a&gt;). &lt;/li&gt;&lt;li&gt;Garantir que conte&amp;uacute;dos s&amp;atilde;o inseridos de forma acess&amp;iacute;vel &lt;/li&gt;&lt;li&gt;N&amp;atilde;o usar tamanhos de fontes muito pequenas (web design) &lt;/li&gt;&lt;li&gt;&lt;div&gt;Testar os sites para acessibilidade usando validators online: &lt;/div&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://validator.w3.org/"&gt;http://validator.w3.org/&lt;/a&gt; &lt;/li&gt;&lt;li&gt;&lt;a href="http://www.acesso.umic.pt/examinator.php"&gt;http://www.acesso.umic.pt/examinator.php&lt;/a&gt; (recomendo pessoalmente) &lt;/li&gt;&lt;li&gt;&lt;a href="http://www.sidar.org/hera/index.php.pt"&gt;http://www.sidar.org/hera/index.php.pt&lt;/a&gt; &lt;/li&gt;&lt;li&gt;&lt;a href="http://www.tawdis.net/"&gt;http://www.tawdis.net/&lt;/a&gt; &lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h5&gt;&lt;strong&gt;Acessibilidade com SharePoint (MOSS) &lt;/strong&gt;&lt;/h5&gt;&lt;p&gt;O Lu&amp;iacute;s deixou alguns conselhos pr&amp;aacute;ticos para melhorar a acessibilidade dos sites em MOSS: &lt;/p&gt;&lt;ul&gt;&lt;li&gt;Incluir textos alternativos para todos os elementos textuais &lt;/li&gt;&lt;li&gt;Utilizar tamanhos de letra relativos (usar font-size na unidade &amp;quot;.em&amp;quot;) em detrimento de tamanhos fixos (&lt;a href="http://www.bigbaer.com/css_tutorials/css_font_size.htm"&gt;http://www.bigbaer.com/css_tutorials/css_font_size.htm&lt;/a&gt; e &lt;a href="http://clagnut.com/blog/348/"&gt;http://clagnut.com/blog/348/&lt;/a&gt;) &lt;/li&gt;&lt;li&gt;Em WCM, evitar usar Web parts &lt;span style="font-family:Wingdings;"&gt;J&lt;/span&gt; ou alterar forma de renderiza&amp;ccedil;&amp;atilde;o das Web part zones &lt;/li&gt;&lt;li&gt;Utilizar sempre que poss&amp;iacute;vel controlos de publica&amp;ccedil;&amp;atilde;o MOSS ou web controls ASP.NET sempre que poss&amp;iacute;vel em deterimento de web parts &lt;/li&gt;&lt;li&gt;Incorpora&amp;ccedil;&amp;atilde;o de solu&amp;ccedil;&amp;atilde;o de terceiros para edi&amp;ccedil;&amp;atilde;o de conte&amp;uacute;dos (Telerik RAD Editor &amp;ndash; W3C WAG level A) &lt;/li&gt;&lt;li&gt;Come&amp;ccedil;ar sempre por desenhar master page m&amp;iacute;nima &lt;/li&gt;&lt;li&gt;Validar p&amp;aacute;gina para acessibilidade = validar master page + validar page layouts + validar conte&amp;uacute;dos &lt;/li&gt;&lt;li&gt;Nos menus SharePoint, n&amp;atilde;o usar a classe Menu do ASP.NET mas antes renderizar &amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;. &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Encontra-se em &lt;a href="http://www.codeplex.com/aks"&gt;http://www.codeplex.com/aks&lt;/a&gt; o Accessibility Toolkit for SharePoint (AKS), um conjunto de templates, master pages, controlos e web parts acess&amp;iacute;veis. Este toolkit &amp;eacute; instalado atrav&amp;eacute;s de um solution package (.wsp) e cont&amp;eacute;m altera&amp;ccedil;&amp;otilde;es &amp;agrave; implementa&amp;ccedil;&amp;atilde;o das web part zones. Na pr&amp;oacute;xima vers&amp;atilde;o do AKS vai ser lan&amp;ccedil;ado um gestor de conte&amp;uacute;dos acess&amp;iacute;vel (Accessible Rich Text Editor [aRTE]). O roadmap do AKS encontra-se dispon&amp;iacute;vel em &lt;a href="http://blogs.msdn.com/sharepoint/archive/2008/03/12/announcing-accessibility-kit-for-sharepoint-1-1-and-future-roadmap.aspx"&gt;http://blogs.msdn.com/sharepoint/archive/2008/03/12/announcing-accessibility-kit-for-sharepoint-1-1-and-future-roadmap.aspx&lt;/a&gt;. &lt;/p&gt;&lt;h4&gt;DEV06 - ADO.NET Entity Framework e LINQ To Entities &lt;/h4&gt;&lt;p&gt;Orador: Lu&amp;iacute;s Falc&amp;atilde;o (ISEL) &lt;/p&gt;&lt;p&gt;Nesta sess&amp;atilde;o foi abordada a ADO.NET Entity Framework (&lt;a href="http://msdn2.microsoft.com/en-us/library/aa697427(VS.80).aspx"&gt;http://msdn2.microsoft.com/en-us/library/aa697427(VS.80).aspx&lt;/a&gt;), uma nova framework cujo objectivo &amp;eacute; o de aumentar o n&amp;iacute;vel de abstrac&amp;ccedil;&amp;atilde;o no que diz respeito &amp;agrave; programa&amp;ccedil;&amp;atilde;o da camada de acesso a dados. Um dos problemas mais comuns no desenho das classes DAL &amp;eacute; o esfor&amp;ccedil;o associado ao mapeamento entre as classes DAL e a BD. A Entity Framework permite facilitar esta tarefa ao disponibilizar um diagrama integrado no Visual Studio 2008. Usando o Solution Explorer &amp;eacute; poss&amp;iacute;vel importar todo a estrutura de uma base de dados para um diagrama de classes que &amp;eacute; a transforma&amp;ccedil;&amp;atilde;o do modelo de dados num modelo de classes mapeado directamente com a estrutura da BD. Depois &amp;eacute; poss&amp;iacute;vel definir novas rela&amp;ccedil;&amp;otilde;es entre as classes, definir heran&amp;ccedil;as entre classes (n&amp;atilde;o &amp;eacute; poss&amp;iacute;vel definir heran&amp;ccedil;a ao n&amp;iacute;vel da BD), mapear os dados de uma classe para que estes sejam divididos entre duas ou mais tabelas entre outras funcionalidades. &lt;/p&gt;&lt;p&gt;Na nova API vem inclu&amp;iacute;do um novo .NET provider para Entity Framework (Entity Client) que &amp;eacute; o correspondente ao SqlClient (para SQL Server) para actuar sobre as entidades criadas com a Entity Framework. &lt;/p&gt;&lt;p&gt;Ainda se encontra em vers&amp;atilde;o beta e nesta fase s&amp;oacute; permite gerar o Entity Model a partir da BD, n&amp;atilde;o permitindo ainda criar primeiro o modelo antes e gerar a BD a partir deste.&lt;/p&gt;&lt;img src="http://blogit.create.pt/aggbug.aspx?PostID=488" width="1" height="1"&gt;</content><author><name>misidoro</name><uri>http://blogit.create.pt/members/misidoro.aspx</uri></author><category term="TechDays" scheme="http://blogit.create.pt/blogs/miguelisidoro/archive/tags/TechDays/default.aspx" /></entry><entry><title>SharePoint 2007 and WSS 3.0 Dispose Patterns by Example</title><link rel="alternate" type="text/html" href="http://blogit.create.pt/blogs/miguelisidoro/archive/2008/02/20/SharePoint-2007-and-WSS-3.0-Dispose-Patterns-by-Example.aspx" /><id>http://blogit.create.pt/blogs/miguelisidoro/archive/2008/02/20/SharePoint-2007-and-WSS-3.0-Dispose-Patterns-by-Example.aspx</id><published>2008-02-20T20:35:22Z</published><updated>2008-02-20T20:35:22Z</updated><content type="html">&lt;p&gt;When developing for the SharePoint platform, developers should be very careful in using the SharePoint API in order to avoid memory leaks in a production SharePoint farm. &lt;a href="http://blogs.msdn.com/rogerla/default.aspx" target="_blank"&gt;Roger Lamb&lt;/a&gt; has written a great &lt;a href="http://blogs.msdn.com/rogerla/archive/2008/02/12/sharepoint-2007-and-wss-3-0-dispose-patterns-by-example.aspx" target="_blank"&gt;post&lt;/a&gt; that shows a series of examples where code can lead to memory leaks and best practices on how to avoid them. Definitely, a must read for all SharePoint developers.
&lt;/p&gt;&lt;p&gt;Another suggestion I leave before deploying any custom development into a SharePoint farm, is to use a stress tool on your SharePoint web site. I recommend using &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=e2c0585a-062a-439e-a67d-75a89aa36495" target="_blank"&gt;Microsoft Web Application Stress Tool&lt;/a&gt; and take a good look into the IIS Application Pool Processes (w3wp.exe) memory consumption in order to ensure they remain stable (you should have one w3wp.exe process for each application pool).&lt;/p&gt;&lt;img src="http://blogit.create.pt/aggbug.aspx?PostID=473" width="1" height="1"&gt;</content><author><name>misidoro</name><uri>http://blogit.create.pt/members/misidoro.aspx</uri></author><category term="Sharepoint 2007" scheme="http://blogit.create.pt/blogs/miguelisidoro/archive/tags/Sharepoint+2007/default.aspx" /></entry><entry><title>SharePoint 2007 - Getting URL from Image Field in WCM Web Sites</title><link rel="alternate" type="text/html" href="http://blogit.create.pt/blogs/miguelisidoro/archive/2007/12/09/SharePoint-2007-_2D00_-Getting-URL-from-Image-Field-in-WCM-Web-Sites.aspx" /><id>http://blogit.create.pt/blogs/miguelisidoro/archive/2007/12/09/SharePoint-2007-_2D00_-Getting-URL-from-Image-Field-in-WCM-Web-Sites.aspx</id><published>2007-12-09T14:40:45Z</published><updated>2007-12-09T14:40:45Z</updated><content type="html">&lt;p&gt;It is a common scenario in WCM web sites, to have content page images stored in a column of type Image. SharePoint stores this kind of fields in the content database by storing the image HTML markup, storing an &amp;lt;IMG&amp;gt; tag like in the following example:
&lt;/p&gt;&lt;p&gt;&amp;lt;IMG src="http://blogit.create.pt/PublishingImages/picture.GIF" /&amp;gt;
&lt;/p&gt;&lt;p&gt;When working in context of a page layout, we can easily include image fields by inserting an Image Field control using SharePoint Designer. However, there are situations where we must use the SharePoint Publishing API and there's where the &lt;strong&gt;ImageFieldValue&lt;/strong&gt; class comes in hand. This class represents an &amp;lt;IMG&amp;gt; tag and its properties. A common situation is when you want to get the Image URL from its HTML markup. This example shows how it can easily be achieved by using the ImageFieldValue class:
&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:10pt;"&gt;&lt;span style="color:blue;"&gt;public&lt;/span&gt;
			&lt;span style="color:blue;"&gt;static&lt;/span&gt;
			&lt;span style="color:blue;"&gt;string&lt;/span&gt; getImageUrl(&lt;span style="color:blue;"&gt;string&lt;/span&gt; imageFieldHTMLMarkup)
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:10pt;"&gt;{            
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:10pt;"&gt;    Microsoft.SharePoint.Publishing.Fields.ImageFieldValue image =
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:10pt;"&gt;
			&lt;span style="color:blue;"&gt;new&lt;/span&gt; Microsoft.SharePoint.Publishing.Fields.ImageFieldValue(imageFieldHTMLMarkup);            
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;
 &lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:10pt;"&gt;
			&lt;span style="color:blue;"&gt;return&lt;/span&gt; image.ImageUrl;
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:10pt;"&gt;}&lt;/span&gt;
	&lt;/p&gt;&lt;p&gt;More information about the ImageFieldValue class can be found in the &lt;a href="http://msdn2.microsoft.com/en-us/library/microsoft.sharepoint.publishing.fields.imagefieldvalue.aspx" target="_blank"&gt;MSDN web site&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://blogit.create.pt/aggbug.aspx?PostID=444" width="1" height="1"&gt;</content><author><name>misidoro</name><uri>http://blogit.create.pt/members/misidoro.aspx</uri></author><category term="Sharepoint 2007" scheme="http://blogit.create.pt/blogs/miguelisidoro/archive/tags/Sharepoint+2007/default.aspx" /><category term="WCM" scheme="http://blogit.create.pt/blogs/miguelisidoro/archive/tags/WCM/default.aspx" /></entry></feed>