• No se han encontrado resultados

Diferencia entre los conceptos de Autarquía y Autonomía

PRINCIPIOS DE AUTONOMIA POLITICA, ADMINISTRATIVA Y FINANCIERIA EN EL FEDERALISMO MEXICANO.

6. Diferencia entre los conceptos de Autarquía y Autonomía

Adding activities is simply a matter of dragging them from the Toolbox and dropping them onto the Designer canvas where we need them. The Designer even helps us out by lighting up each valid location to drop an activity with a small green plus sign icon:

Caution

If you drag an activity out of the Toolbox you’ll see it is possible to add an activity above the onWorkflowActivated activity even though, as I mentioned earlier, the onWorkflowActivated activity needs to be the first activity in our workflow. This is because the Designer does not know to stop us. Having the onWorkflowActivated activity come first is a SharePoint restriction. The Designer will let us build and compile a workflow with another activity first, but if we deploy it and try to run it, SharePoint will yell at us—the exact message is “Correlation value has not been initialized on declaration <correlation_token_name> for activity <name_of_activity>” or something similar, depending on which activity you have first.

To get started with our example, we need the following activities, added in this order, starting right below the onWorkflowActivated activity:

• LogToHistoryListActivity—Used to write an entry to the history list for our workflow at the beginning of processing. Set the (Name) property to hlogBegin.

• MacroStripper—The custom activity we wrote in Chapter 5. Set the ID property to

macroStripper.

• IfElse—Branches our workflow conditionally depending on whether the posted document is now macro-free. Leave the ID property at the default.

• ForEach—A custom activity available from Microsoft on the .NET Framework 3.0 site (wf.netfx3.com). I’ll post a link directly to it on my web site: www.kcdholdings.com. Add it to the first branch of the IfElse activity. Leave the ID property at the default.

• Two SendEMail activities, which are part of the SharePoint activity set—Add one inside the ForEach and one just after it. Set the ID properties to emlError for the first and

emlAuthor for the second.

• Another LogToHistoryListActivity—Used to write an entry to the history log at the end of our workflow to indicate the end of our processing. Add it after the IfElse, at the very end of the workflow. Set the ID property to hlogEnd.

Figure 6-4 shows how these activities need to be laid out in the Designer. Simply drag each from the Toolbox and drop it in the proper place. Note that when you drop the IfElse activity, it is going to have two branches by default. For this example, we are not going to do anything in the else branch, so you can either leave it in place but empty, or right-click on it and delete it. I went with the latter simply because it makes things look cleaner. If you ever need it back again, you can always add another branch via the context menu.

Figure 6-4. The Workflow Designer

Another interesting thing to note is the LogToHistoryList activity. As covered in Chapter 3, the history list for our workflow is set up by an administrator when they associate our workflow with a document library. What this means to us is that we have no idea of the name, URL, or any other details of the history list. So how do we write information to a list we know almost nothing about? We don’t. That’s why this activity exists. We tell this activity the information we’d like to record, and the SharePoint workflow host does some magic behind the scenes to write this information to the proper history list. If you ask me, it’s a rather slick solution to a somewhat thorny problem.

With each of the activities in place, you can get a good picture of how the workflow will run, as shown in Figure 6-4. This is why I like to drop all of my activities first. It lets me look at my workflow as a whole and make sure I get all of the pieces laid out before I start customizing them. This is obviously a very simple workflow; nonetheless, it helps to have the activities all set in the proper order before you go setting properties and writing code.

Note

If you look at Figure 6-4, you’ll see an unfamiliar activity—the ForEach activity. This does not ship out of the box, and is not part of the SharePoint activities. Back in Chapter 5, I mentioned one additional source of activities—the WF and SharePoint developer communities. ForEach is a perfect example of the former. It was posted to the Microsoft workflow community site as a sample activity for use in WF workflows. Because our Office workflows are nothing more than specialized WF workflows, we can make use of it. You can get your hands on this little treasure at wf.netfx3.com.

You’ll notice in Figure 6-4 that some of our activities each have an error indicator—the small red circle with the exclamation point inside. This is design-time validation. The author of these activities is telling us that we need to take some action in order to use these activities. We touched on this in Chapter 5 when we were creating our custom activity and writing our custom validators. Here it is in action.

You can probably guess what each activity needs, but to see for sure, move your mouse over the error indicator and click on the drop-down arrow that appears. This smart tag tells us exactly what we need to do in order for our instance of the activity to pass the validation test, as indicated in Figure 6-5.

Figure 6-5. Smart tags warn us of validation errors before we compile.

Tip

For missing property value errors such as this one, if you click on the error message itself, it will take you directly to the appropriate place in the Properties window where you need to take action.

With our activities in place, we can go in and start setting properties—not only to fix validation errors, but also to just get the workflow doing what we need. Table 6-2 shows the properties that need to be set for each activity. As you’re changing the properties for each activity, take a look around at the other properties. You’ll begin to get a good sense of what is possible.

Table 6-2. Setting Properties on Our Workflow Activities

Activity Property New Value Description

onWorkflowActivated1 CorrelationToken workflowToken For information on corre-

lation tokens, see the sidebar “Correlation Tokens?” later in this chapter.

onWorkflowActivated1 CorrelationToken\

OwnerActivityName

DocCleanerWF For information on corr- elation tokens, see the sidebar “Correlation Tokens?” later in this chapter. onWorkflowActivated1 workflowProperties\ Name DocCleanerWF onWorkflowActivated1 workflowProperties\ Path

workflowProperties The name of the variable that represents our

SPWorkflowActivation ➥

Properties object. This object is created auto- matically and the name cannot be edited here.

hlogBegin EventID WorkflowStarted

hlogBegin MethodInvoking setBeginLog After you enter the method

name here, Visual Studio will jump you over to Code view with a method signature created for you. The code for this is in Listing 6-3.

macroStripper PayloadItem workflowProperties.

Item

This dependency property cannot be edited directly. Click on either the ellipsis in the value field or the small blue information icon to load the Binding dialog box. Navigate down to workflowProperties.

Item, as shown in

Figure 6-6.

ifElseBranchActivity1 Condition Declarative Rule

Condition

We go into much more detail on rules and conditions in Chapter 8.

ifElseBranchActivity1 ConditionName <leave blank> I’ll walk you through

setting this in just a minute.

ifElseBranchActivity1 ConditionExpression <leave blank> I’ll also walk you through

setting this in just a minute.

forEach1 Items workflowProperties. Item.ParentList. ParentWeb.

AssociatedOwnerGroup. Users

Like the payloadItem

property earlier, you can again use the Binding dialog box to set this property (but you’ll have to access it via the little blue icon). For our scenario, we’re going to

use the Owners collection

for our SharePoint site. The forEach property will iterate through its child activities once for every member of this collection.

emlError CorrelationToken workflowToken You can just select this

from the drop-down. For information on correlation tokens, see the sidebar “Correlation Tokens?” later in this chapter.

emlError From <a valid email address

in your environment>

emlError MethodInvoking sendErrorEmail After you enter the method

name here, Visual Studio will jump you over to Code view with a method signature created for you. The code for this is in Listing 6-1.

emlError Subject Error Removing Macros

emlAuthor CorrelationToken workflowToken You can just select this

from the drop-down. For information on correlation tokens, see the sidebar “Correlation Tokens?” later in this chapter.

emlAuthor From <a valid email address

in your environment>

emlAuthor MethodInvoking sendAuthorEmail After you enter the method

name here, Visual Studio will jump you over to Code view with a method sig- nature created for you. The code for this is in Listing 6-2.

emlAuthor Subject Document at KCD

Holdings Client Portal

Table 6-2. Setting Properties on Our Workflow Activities (Continued)

Note

When you have finished setting all of the property values indicated in Table 6-1, there will still be an error indicator on the onWorkflowActivated activity. To get rid of this, you will need to edit the Designer file (DocCleaner.designer.cs). Find the line that reads activitybind.Name = "Workflow1" and change it to read activitybind.Name="DocCleanerWF". For some reason this isn’t updated when we rename our workflow code file.

Figure 6-6. This dialog box allows you to connect properties to elements of your workflow.

hlogEnd EventId workflowCompleted

hlogEnd MethodInvoking setEndLog After you enter the method

name here, Visual Studio will jump you over to Code view with a method signa- ture created for you. The code for this is in Listing 6-4. Table 6-2. Setting Properties on Our Workflow Activities (Continued)

Caution

Interestingly, the validator for the SendEmail activity does not make us set any of the typical information associated with sending an email—To, From, Subject, Body, etc. Presumably this is because this information is, or can be, set in code. However, be aware that you will not receive any warnings about this in the Designer or when you build your workflow. At runtime, your activity will throw an error when it tries to execute the SendEmail activity if this information is not set. You can either set the properties directly or set them via the Headers property.

Table 6-2 takes care of setting most of our properties. We’ll get to the code for the couple of activities that need it in a moment. First, if you click back into the Designer view, you’ll see that we still have a validation error in one of our activities—the IfElseBranch. If you click on the error indicator on the Designer, you’ll see the smart tag pop up that tells you that the Condition

property is not set. In order to tackle this one, we need to take a brief foray into activity condi- tions. We go much further into this topic in Chapter 8; we’ll just touch upon it here.

For now, think of conditions as a mechanism for determining the circumstances under which an activity executes. It can get more complex than that, but that’s a pretty close first pass. By way of example, the simplest condition is on a basic IfElseBranch activity—such as we have in our scenario. The logic of the activity is pretty straightforward—if a certain condition is true, execute the activities in the branch; otherwise, move on to the second branch and evaluate its condition. While this logic can certainly get more complicated, all activity conditions essen- tially break down to this simple state, and the heart of this logic is the condition that is evaluated.

The condition that is evaluated must result in either a true or a false. Each activity that contains this logic will take different actions based on the return value from the condition eval- uation, but the expression itself always results in a Boolean evaluation. Conditions can be applied as either of the following:

• A Code Condition, which means that you write code that results in a Boolean value to indicate whether or not the condition evaluates to true or false, thereby controlling how the activity processes.

• A Declarative Rule Condition, which means that you define the logic that controls how the activity processes utilizing the built-in Condition Editor. Technically, you’re still writing code in the Condition Editor, but the code itself is simpler since it consists of basic comparisons between fields, variables, and values.

Selecting between these two options is done in the Properties window for your activity, as shown in Figure 6-7.

Figure 6-7. You select which type of condition to use in the Properties window.

For our IfElseBranch activity, we’re going to make use of a Declarative Rule Condition, so go ahead and select it in the drop-down in the Properties window. After you make that selec- tion, expand the Condition property and you’ll see that we now have two subproperties to set—

ConditionName and Expression. Clicking in the ConditionName field will show a small ellipsis button. Click this button to launch the Condition Editor, shown in Figure 6-8.

Figure 6-8. The Condition Editor allows you to specify conditions.

Again, we’ll look at this tool further in Chapter 8, so for now, just click the New button, type a condition of this.macroStripper.IsMacroFree != True, and we’ll move on. Save your condi- tion and return to the Designer. You’ll notice that none of our activities now show a validation error. If we were impatient, we could build our solution and not receive any errors. But we’re not impatient, are we?