.NET
  Home arrow .NET arrow Completing a Business Layer with Windows W...
ASP Free Forums 
.NET  
ASP  
ASP Code  
ASP.NET  
ASP.NET Code  
BrainDump  
C#  
Code Examples  
Database  
Database Code  
IIS  
Microsoft Access  
MS SQL Server  
Silverlight  
Visual Basic.NET  
Windows Scripting  
Windows Security  
XML  
Mobile Linux 
App Generation ROI 
IBM® developerWorks 
ASP Web Hosting  
ASP.NET Web Hosting 
Windows Web Hosting
 
Weekly Newsletter
 
Developer Updates  
Free Website Content 
 RSS  Articles
 RSS  Forums
 RSS  All Feeds
Write For Us Get Paid 
Request Media Kit
Contact Us 
Site Map 
Privacy Policy 
Support 
 USERNAME
 
 PASSWORD
 
 
  >>> SIGN UP!  
  Lost Password? 
.NET

Completing a Business Layer with Windows Workflow Foundation
By: O'Reilly Media
  • Search For More Articles!
  • Disclaimer
  • Author Terms
  • Rating: 5 stars5 stars5 stars5 stars5 stars / 1
    2009-11-23

    Table of Contents:
  • Completing a Business Layer with Windows Workflow Foundation
  • Implementing the DashboardFacade
  • Implementing the WorkflowHelper Class
  • Implementing the DashboardFacade

  • Rate this Article: Poor Best 
      ADD THIS ARTICLE TO:
      Del.ici.ous Digg
      Blink Simpy
      Google Spurl
      Y! MyWeb Furl
    Email Me Similar Content When Posted
    Add Developer Shed Article Feed To Your Site
    Email Article To Friend
    Print Version Of Article
    PDF Version Of Article
     
     
    ADVERTISEMENT


    Completing a Business Layer with Windows Workflow Foundation


    (Page 1 of 4 )

    In this conclusion to a three-part article, we'll finish our discussion of how Windows Workflow Foundation can help us create an important layer of an application. It is excerpted from chapter four of the book Building a Web 2.0 Portal with ASP.NET 3.5, written by Omar Al Zabir (O'Reilly, 2008; ISBN: 0596510500). Copyright © 2008 O'Reilly Media, Inc. All rights reserved. Used with permission from the publisher. Available from booksellers or direct from O'Reilly Media.

    Adding a New Tab (AddNewTabWorkflow)

    Adding a new tab is quite simple, requiring only two steps, after the GUID is assigned (see Figure 4-7):

    1. Create a new blank page. 
       
    2. Update the user settings and set the new page as the current page.

    Moving Widgets (MoveWidgetInstanceWorkflow)

    To move a widget, you must do the following (see Figure 4-8):

    1. Ensure the current user who is calling the workflow owns the widget instance. 
       
    2. Fetch the widget instance and put in workflow context so that other activities can use it. 
       
    3. Pull the widget up from its previous position, which means all the widgets below are shifted up. 
       
    4. Push the widget onto its new position so that all widgets on the new column move down. 
       
    5. Update the widget’s position.

      

     
    Figure 4-7.  AddNewTabWorkflow design view

     
    Figure 4-8.  MoveWidgetInstanceWorkflow design view

    MoveWidgetInstanceWorkflow verifies whether the widget being moved is really the current user’s widget. This is necessary to prevent malicious web service hacking (see the “Implementing Authentication and Authorization” section in Chapter 3). TheEnsureOwnerActivitycan check both the page and the widget’s ownership (see Example 4-24).

    Example 4-24. EnsureOwnerActivity Execute function

    protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)
    {
      var db = DatabaseHelper.GetDashboardData();

      if( this.PageId == 0 && this.WidgetInstanceId == 0 )
      {
        throw new ApplicationException("No valid object specified to check");
      }

      if( this.WidgetInstanceId > 0 )
      {
        // Gets the user who is the owner of the widget. Then sees if the current user is the
       same.
        var ownerName = (from wi in db.WidgetInstances
            where wi.Id == this.WidgetInstanceId
            select wi.Page.AspnetUser.LoweredUserName).First();

        if( !this.UserName.ToLower().Equals( ownerName ) )
          throw new ApplicationException(string.Format("User {0} is not the owner of the
          widget instance {1}", this.UserName, this.WidgetInstanceId));
     
    }

      if( this.PageId > 0 )
      {
        // Gets the user who is the owner of the page. Then sees if the current user is the
       same.
        var ownerName = (from p in db.Pages
            where p.ID == this.PageId
            select p.AspnetUser.LoweredUserName).First();

        if( !this.UserName.ToLower().Equals( ownerName ) )
          throw new ApplicationException(string.Format("User {0} is not the owner of the page
          {1}", this.UserName, this.PageId));
     
    }

      return ActivityExecutionStatus.Closed;
    }

    EnsureOwnerActivitytakesUserNameand eitherWidgetInstanceIdorPageId and verifies the user’s ownership. It should climb through the hierarchy fromWidgetInstanceto thePageand then toAspnetUser to check whether the username matches or not. If the username is different than the one specified, then the owner is different and it’s a malicious attempt.

    CheckingPageownership requires just going one level up toAspnetUser. But checkingWidgetInstanceownership requires going up to the container page and then checking ownership of the page. This needs to happen very fast because it is called on almost every operation performed onPage orWidgetInstance. This is why you want to make sure it does a scalar select only, which is faster than selecting a full row.

    Once the owner has been verified, the widget can be placed on the right column. The next activity,PutWidgetInstanceInWorkflow, does nothing but put theWidgetInstanceobject into a public property according to its ID so the object can be manipulated directly. The other activities in the workflow work with the object’sColumnNoandOrderNoproperties. The next step,PushWidgetsDownInNewColumn, calls thePushDownWidgetsOnColumnActivity, which pushes widgets down one row so there’s a room for a new widget to be dropped (see Example 4-25).

    Example 4-25. PushDownWidgetsOnColumnActivity Execute function

    protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)
    {
     
    var db = DatabaseHelper.GetDashboardData();
     
    var query = from wi in db.WidgetInstances
           
    where wi.PageId == PageId && wi.ColumnNo == ColumnNo && wi.OrderNo >= Position
           orderby wi.OrderNo
          
    select wi;
      List<WidgetInstance>list = query.ToList();

      int orderNo = Position+1;
     
    foreach( WidgetInstance wi in list )
     
    {
       
    wi.OrderNo = orderNo ++;
      }

      db.SubmitChanges();

      return ActivityExecutionStatus.Closed;
    }

    The idea is to move all the widgets right below the position of the widget being dropped and push them down one position. Now we have to update the position of the dropped widget using the activityChangeWidgetInstancePositionActivity(see Example 4-26).

    Example 4-26. ChangeWidgetInstancePositionActivity Execute function

    protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)
    {
     
    WidgetInstance widgetInstance = DatabaseHelper.GetDashboardData().WidgetInstances.
     
    Single( wi => wi.Id == WidgetInstanceId );

      DatabaseHelper.Update<WidgetInstance>( widgetInstance, delegate( WidgetInstance wi )
      {
       
    wi.ColumnNo = ColumnNo;
       
    wi.OrderNo = RowNo;
      });

      return ActivityExecutionStatus.Closed;
    }

    The widget is placed on a new column, and the old column has a vacant place. But now we need to pull the widgets one row upward on the old column.ReorderWidgetInstanceOnColumnActivityfixes row orders on a column, eliminating the gaps between them (see Example 4-27). The gap in the column will be fixed by recalculating the row number for each widget on that column, starting from zero.

    Example 4-27. ReorderWidgetInstanceOnColumnActivity Execute function

    protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)
    {
     
    var db = DatabaseHelper.GetDashboardData();
     
    var query = from wi in db.WidgetInstances
            where wi.PageId == PageId && wi.ColumnNo == ColumnNo
            orderby wi.OrderNo
            select wi;
      List<WidgetInstance>list = query.ToList();

      int orderNo = 0;
      foreach( WidgetInstance wi in list )
      {
       
    wi.OrderNo = orderNo ++;
      }

      db.SubmitChanges();

      return ActivityExecutionStatus.Closed;
    }

    That’s all that is required for a simple drag-and-drop operation.

    More .NET Articles
    More By O'Reilly Media


     

    .NET ARTICLES

    - Introducing .NET
    - Building Business Objects for an Application
    - Methods for an Application`s Business Logic ...
    - Properties of an Application`s Business Logi...
    - Classes and Properties in an Application`s B...
    - Organizing Code for the Business Logic Layer...
    - Building the Business Logic Layer
    - Completing a Business Layer with Windows Wor...
    - Building Applications with Windows Workflow ...
    - Building the Data and Business Layers Using ...
    - The Transformed XML Explorer in MFC
    - List Control and Property Grid with the MFC ...
    - Font, Shell and Masked Edit Controls for MFC
    - Color, Link and Image Editor Controls for M...
    - New Controls for MFC





    © 2003-2010 by Developer Shed. All rights reserved. DS Cluster 4 Hosted by Hostway
    For more Enterprise Application Development news, visit eWeek