Business Rules/Logic

Labels
AJAX(112) App Studio(7) Apple(1) Application Builder(245) Application Factory(207) ASP.NET(95) ASP.NET 3.5(45) ASP.NET Code Generator(72) ASP.NET Membership(28) Azure(18) Barcode(2) Barcodes(3) BLOB(18) Business Rules(1) Business Rules/Logic(140) BYOD(13) Caching(2) Calendar(5) Charts(29) Cloud(14) Cloud On Time(2) Cloud On Time for Windows 7(2) Code Generator(54) Collaboration(11) command line(1) Conflict Detection(1) Content Management System(12) COT Tools for Excel(26) CRUD(1) Custom Actions(1) Data Aquarium Framework(122) Data Sheet(9) Data Sources(22) Database Lookups(50) Deployment(22) Designer(177) Device(1) DotNetNuke(12) EASE(20) Email(6) Features(101) Firebird(1) Form Builder(14) Globalization and Localization(6) How To(1) Hypermedia(2) Inline Editing(1) Installation(5) JavaScript(20) Kiosk(1) Low Code(3) Mac(1) Many-To-Many(4) Maps(6) Master/Detail(36) Microservices(4) Mobile(63) Mode Builder(3) Model Builder(3) MySQL(10) Native Apps(5) News(18) OAuth(9) OAuth Scopes(1) OAuth2(13) Offline(20) Offline Apps(4) Offline Sync(5) Oracle(11) PKCE(2) Postgre SQL(1) PostgreSQL(2) PWA(2) QR codes(2) Rapid Application Development(5) Reading Pane(2) Release Notes(183) Reports(48) REST(29) RESTful(29) RESTful Workshop(15) RFID tags(1) SaaS(7) Security(81) SharePoint(12) SPA(6) SQL Anywhere(3) SQL Server(26) SSO(1) Stored Procedure(4) Teamwork(15) Tips and Tricks(87) Tools for Excel(2) Touch UI(93) Transactions(5) Tutorials(183) Universal Windows Platform(3) User Interface(338) Video Tutorial(37) Web 2.0(100) Web App Generator(101) Web Application Generator(607) Web Form Builder(40) Web.Config(9) Workflow(28)
Archive
Blog
Business Rules/Logic
Saturday, March 31, 2012PrintSubscribe
Shared Business Rules

The core framework of your application always tries to create a class with the name YourProjectNamespace.Rules.SharedBusinessRules whenever it receives a request to process data on the server. The framework interacts with the class instance in order to determine if any custom business logic is implemented in the application. This happens when data is selected, updated, inserted, deleted, and when custom actions are requested.

The name YourProjectNamespace in the namespace entered in the project settings. The default namespace is MyCompany.

Project namespace configuration in the line-of-business application created with Code OnTime web application generator

You can enable shared business rules if you select Settings of your project and choose the Business Logic Layer option. Toggle the check box in the Shared Business Rules section, click Finish button to save the changes.

Enabling shared business rules in a Code On Time web application

If you generate the app then the class file SharedBusinessRules.cs(vb) will be created either in ~/App_Code/Rules folder on in the ~/Rules folder of the application class library. This depends on the type of your projects.

'SharedBusinessRules' code file in the Solution Explorer of a 'Web Site Factory' project

Class SharedBusinessRules provides a convenient placeholder for the business logic that may apply to all data controllers of your web application.

Enter the following code in the code file of shared business rules.

C#:

using System;
using System.Data;
using System.Collections.Generic;
using System.Linq;
using MyCompany.Data;

namespace MyCompany.Rules
{
    public partial class SharedBusinessRules : MyCompany.Data.BusinessRules
    {
        [ControllerAction("", "grid1", "Select", ActionPhase.Before)]
        protected void TellTheUserWhatJustHappened()
        {
            if (!IsTagged("UserIsInformed"))
            {
                Result.ShowMessage(
                    "You just have requested data from '{0}' controller", 
                    ControllerName);
                AddTag("UserIsInformed");
            }
        }
    }
}

Visual Basic:

Imports MyCompany.Data
Imports System
Imports System.Collections.Generic
Imports System.Data
Imports System.Linq

Namespace MyCompany.Rules

    Partial Public Class SharedBusinessRules
        Inherits MyCompany.Data.BusinessRules

        <ControllerAction("", "grid1", "Select", ActionPhase.Before)>
        Protected Sub TellTheUserWhatJustHappened()
            If (Not IsTagged("UserIsInformed")) Then
                Result.ShowMessage(
                    "You just have requested data from '{0}' controller",
                    ControllerName)
                AddTag("UserIsInformed")
            End If
        End Sub

    End Class
End Namespace

Save the file and navigate to any page of your web application that contains data. Here is what you will see at the top of the page if you view the Suppliers in the Northwind sample.

The message from the shared business rule method TellTheUserWhatJustHappened displays a message at the top of the page when data is selected for the first time

If you continue sorting, filter, and paging the suppliers then the message will continue to be displayed at the top. If you start editing or select a supplier then the message from the child view will popup.

The message from the shared business rules is displayed when the child products are selected for the first time

We are using IsTagged and AddTag methods to display the messages once in the lifecycle of the page instance in the browser window. If the data view on the page is not tagged then the message is displayed and the tag UserIsInformed is assigned to it.

The message will eventually disappear as soon as user invokes available data view actions.

Method TellTheUserWhatJustHappened is called every time the data is selected. This happens when the data is sorted, paged, changed, or if a filter is applied. Data view tagging ensures that the message will be sent to the client one time only.

If you navigate away from the page and come back using the Back button of your web browser then the tag is restored and no message will be displayed. If you click ahead and arrive to a non-historical version of the page then the data view tags will be blank and the message will show up once when the first attempt to select data is executed on the server.

The business logic implemented in this shared business rules example will be engaged for all data pages of your web application whenever the grid1 view of any controller requires data. This applies to an application with a single data page and will also be true in the application with three hundred data pages.

If you have existing controller-specific business rules, then make sure that their base class is changed from BusinessRules to SharedBusinessRules. If you create new controller-specific business rules, then the code generator will automatically specify the SharedBusinessRules class as their base.

Sunday, March 18, 2012PrintSubscribe
Total and Subtotal: Business Rule for Subtotal

The Subtotal field is now present in the application. The field does not reflect changes when new order items are entered. We will add a business rule to the Orders controller and add a code expression for Subtotal. This code expression will use the rule to calculate the subtotal.

In the Project Explorer, switch to Controllers tab. Double-click on the Orders controller. In the Handler field, type:

OrdersBusinessRules

Adding 'OrdersBusinessRules' Handler to 'Orders' Controller

Press OK to save the controller, exit the Designer, and Generate the project. The business rule placeholder file will be created.

When generation is complete, click on the project name in the web application generator and press Develop. Microsoft Visual Studio or Visual Web Developer will open. In the Solution Explorer on the right side of the screen, double-click on App_Code /Rules / OrdersBusinessRules.cs(vb).

OrdersBusinessRules.cs Rule file in OrderForm project

Paste in the following code:

C#:

using MyCompany.Data;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
namespace MyCompany.Rules
{
    public partial class OrdersBusinessRules : MyCompany.Data.BusinessRules
    {
        public decimal CalculateOrderDetailsTotal(int? orderID)
        {
            using (SqlText calc = new SqlText(@"select sum(unitprice * 
                    quantity * (1 - discount)) from 
                    [Order Details] where OrderID= @OrderID"))
            {
                calc.AddParameter("@OrderID", orderID);
                object total = calc.ExecuteScalar();
                if (DBNull.Value.Equals(total))
                    return 0;
                else
                    return Convert.ToDecimal(total);
            }
        }
    }
}

VB:

Imports MyCompany.Data
Imports System
Imports System.Collections.Generic
Imports System.Data
Imports System.Linq
Namespace MyCompany.Rules

    Partial Public Class OrdersBusinessRules
        Inherits MyCompany.Data.BusinessRules
        Public Function CalculateOrderDetailsTotal(
                            ByRef orderID As Nullable(Of Integer)) As Decimal
            Using calc As SqlText = New SqlText(
                    "select sum(unitprice * quantity * (1 - discount)) " +
                    "from [Order Details] where OrderID=@OrderID")
                calc.AddParameter("@OrderID", orderID)
                Dim total As Object = calc.ExecuteScalar()
                If DBNull.Value.Equals(total) Then
                    Return 0
                Else
                    Return Convert.ToDecimal(total)
                End If
            End Using
        End Function
    End Class
End Namespace

This function uses SqlText utility class to create an instance of a query connected to the project’s database.
This simple query selects a sum of UnitPrice multiplied by Quantity multiplied by one minus the
Discount.

Note that SqlText utility class is generated as a part of the code base of your application. It uses the
default database connection string and ADO.NET to execute the query.

Save the file, and switch back to the application generator. Select the project name, and press Design. In the Project Explorer, switch to Controllers. Double-click on Orders / Fields / Subtotal. Make the following changes:

Property Text
The value of this field is calculated by a business rule expression True
Code Formula
CalculateOrderDetailsTotal(orderID)
Context Fields OrderDetails

Code Formula for 'Subtotal' field
'Context Fields' property of Orders / Fields / Subtotal

Press OK to save the field. The Subtotal field on the Order Form will now update to reflect any changes made to the order details.

Wednesday, March 14, 2012PrintSubscribe
SPContext and SharePoint Factory

ASP.NET developers depend on the intrinsic  objects exposed as properties Request, Response, Session, and a few others in the code classes inherited from System.Web.UI.Page and System.Web.UI.UserControl.  Everything there is to know about the current web request and mechanism to produce an adequate response is encapsulated in these objects.

Microsoft SharePoint application developers similarly depend on the class Microsoft.SharePoint.SPContext also known as SharePoint Context.

ASP.NET developers may tap in the application foundational infrastructure  via System.Web.HttpContext class when programming web request processing logic outside of the boundaries of pages and user controls. For example, Code On Time applications are extended with business rules, which are not based on the pages. The application framework creates business rules classes in response to AJAX requests to process custom aspects of the application business logic.

For example, the following business rule written in Visual Basic will keep assigning an ever increasing generic label “New Product N” by replacing “N” with the counter whenever a new product is created in the Northwind sample.

Imports MyCompany.Data
Imports System

Namespace MyCompany.Rules

    Partial Public Class ProductsBusinessRules
        Inherits MyCompany.Rules.SharedBusinessRules

        <RowBuilder("Products", RowKind.New)> _
        Public Sub PrepareNewProductRow()
            Dim count As Nullable(Of Integer) = HttpContext.Current.Session("ProductCount")
            If Not count.HasValue Then
                count = 1
            Else
                count = count + 1
            End If
            HttpContext.Current.Session("ProductCount") = count
            UpdateFieldValue("ProductName", "New Product " + count.ToString())
        End Sub

    End Class
End Namespace

The method interacts with the user session object via Current static property of HttpContext class.

HttpContext.Current.Session("ProductCount")

SharePoint developers use exactly the same technique. The entire universe of Microsoft SharePoint server infrastructure is available via Current static property of SPContext class.

Business rule developers can take advantage of the shortcut property named Current to make interaction with ASP.NET runtime a little shorter.

Context.Session("ProductCount")

There is no shortcut that would allow access the SharePoint Context in the same fashion. As a matter of fact the application class library in a SharePoint Factory project does not even reference Microsoft SharePoint assemblies.

We have deliberately constructed the SharePoint Factory application generation project to be a solution composed of three Visual Studio projects. Only the project named WebParts is directly dependent on the SharePoint .

SharPoint Factory project in Solution Explorer

The class library of the project incorporates the entire application source code and resources including JavaScript, images, and CSS style sheets. Project named WebApp is used by the application generator to preview the application at design time.

Injection of SharePoint dependencies in either the class library or WebApp will make it impossible to preview the result of project customization. SharePoint is a 64-bit environment. Code On Time relies on IIS Express, the 32-bit application, for preview of generated web sites. These two are simply not compatible.

If you are building line-of-business web applications then having a direct SharePoint dependency can become obsolete with SharePoint Factory. In a matter of minutes your can generate an app straight from your database, customize it without having any idea about the actual intricacies of development with the rather complex SharePoint environment. Publish your application and the WebParts project will make the miracle of turning your app in a native citizen of the SharePoint Server a reality.

If you do need to take full advantage of vast capabilities of Microsoft SharePoint then with a little bit of effort you will outperform your peers and deliver amazing native SharePoint apps – SharePoint Factory will not let you down.

Right-click the WebParts project of your solution and select Set as StartUp Project option in the context menu.

Expand the class library node of the solution, right-click References. Select option Add Reference. Note that if you are developing a Visual Basic application then right-click the class library project name instead.

Adding a reference to Microsoft SharePoint to the class library project of a SharePoint Factory project

Find the SharePoint namespace on the .NET tab of Add Reference dialog and click OK.

SharePoint assembly in 'Add Reference' window

Choose File | Save All option in the Visual Studio menu.

Start the web application generator, click on the name of your project and choose Settings. Select Business Logic Layer and proceed to enable shared business rules.

Enabling shared business rules in a Code On Time web application

Click Finish button. You will end up on the Summary page. Click Cancel  to return to the start page of the generator.

Select the project name on the start page of the application generator one more time and choose Settings. Activate Web Server Configuration settings

Uncheck “Run application upon completion of code generation” option and click Finish.

Disabling automatic launching of the application upon completion of code generation in Code On Time web application generator

This time generate your project.

Select the project name on the start page and choose Develop to launch the Visual Studio development environment. You will be prompted to authorize the elevated permissions required for SharePoint development.

Double-click the shared business rules class of the class library project to open it in the text editor.

Shared Business Rules class in a Code On Time web application

Enter the following code in the class definition. The class implements a method that allows verifying if a the current SharePoint application user belong to a certain SharePoint user group.

C#

using System;
using System.Data;
using System.Collections.Generic;
using System.Linq;
using MyCompany.SPDemo.Data;
using Microsoft.SharePoint;

namespace MyCompany.SPDemo.Rules
{
    public partial class SharedBusinessRules : MyCompany.SPDemo.Data.BusinessRules
    {

        public bool BelongsToGroup(string name)
        {
            foreach (SPGroup group in SPContext.Current.Web.CurrentUser.Groups)
                if (group.Name.Equals(name))
                    return true;
            return false;
        }
    }
}

Visual Basic:

Imports MyCompany.SPDemoVB.Data
Imports System
Imports System.Collections.Generic
Imports System.Data
Imports System.Linq
Imports Microsoft.SharePoint

Namespace Rules

    Partial Public Class SharedBusinessRules
        Inherits MyCompany.SPDemoVB.Data.BusinessRules

        Public Function BelongsToGroup(ByVal name As String) As Boolean
            For Each group As SPGroup In SPContext.Current.Web.CurrentUser.Groups
                If (group.Name.Equals(name)) Then
                    Return True
                End If
            Next
            Return False
        End Function

    End Class
End Namespace

Microsoft SharePoint takes advantage of Windows Active Directory and also contributes a proprietary method of organizing users. This method empowers SharePoint administrators to create application-specific user groups that do not necessarily match the corporate domain organization.

Our method will scan the groups assigned to the current user and will return true if the match is found.

The base class BusinessRules implements the method UserIsInRole. The method allows verifying if the current user is a member of an Active Directory user group. Our new addition effortlessly enhances the framework with the ability to analyze membership in the SharePoint user groups.

Let’s take advantage of this method.

Click on the project name on the start page of the code generator and select Design. Activate the Controllers tab in Project Explorer and double-click any data controller. Our sample has been built from the Adventure Works 2008 R2 database. We will customize the HumanResources_Shift data controller. Enter the name of the custom business rule class that will handle the life-cycle of your data controller.

We have entered “ShiftBusinessRules” in the Handler property. Make sure to click OK button to save the changes.

'Handler' property of the business rules class in SharePoint Factory web application created from 'Adventure Works' database

Exit the designer and click Generate.

Return to Visual Studio – you will be prompted to reload the project.

The new file will show in the project solution under the Rules folder of the application class library.

'ShiftBusinessRules' class in SharePoint Factory project

Double-click the file name and enter the following code.

C#:

using System;
using System.Data;
using System.Collections.Generic;
using System.Linq;
using MyCompany.SPDemo.Data;
using System.Xml;
using System.Xml.XPath;

namespace MyCompany.SPDemo.Rules
{
    public partial class ShiftBusinessRules : MyCompany.SPDemo.Rules.SharedBusinessRules
    {
        public override bool SupportsVirtualization(string controllerName)
        {
            return true;
        }

        public override void VirtualizeController(string controllerName,
            XPathNavigator navigator, XmlNamespaceManager resolver)
        {
            if (BelongsToGroup("Team Site Owners"))
            {
                XPathNavigator grid1 = navigator.SelectSingleNode(
                    "//c:view[@id='grid1']/c:headerText", resolver);
                if (grid1 != null)
                    grid1.SetValue(
                        "Welcome, <b>Site Owner</b>. These are the shifts that you can see.");
            }
        }

        [AccessControl("", "ShiftID", "[Name]='Night'")]
        public void ShowTheNightShiftOnlyToTeamSiteOwners()
        {
            if (BelongsToGroup("Team Site Owners"))
                RestrictAccess();
        }
    }
}

Visual Basic:

Imports MyCompany.SPDemoVB.Data
Imports System
Imports System.Collections.Generic
Imports System.Data
Imports System.Linq
Imports System.Xml
Imports System.Xml.XPath

Namespace Rules
    
    Partial Public Class ShiftBusinessRules
        Inherits MyCompany.SPDemoVB.Rules.SharedBusinessRules

        Public Overrides Function SupportsVirtualization(controllerName As String) As Boolean
            Return True
        End Function

        Public Overrides Sub VirtualizeController(controllerName As String,
                navigator As XPathNavigator, resolver As XmlNamespaceManager)
            If (BelongsToGroup("Team Site Owners")) Then
                Dim grid1 As XPathNavigator = navigator.SelectSingleNode(
                    "//c:view[@id='grid1']/c:headerText", resolver)
                If (Not grid1 Is Nothing) Then
                    grid1.SetValue(
                        "Welcome, <b>Site Owner</b>. These are the shifts that you can see.")
                End If
            End If
        End Sub

        <AccessControl("", "ShiftID", "[Name]='Night'")> _
        Public Sub ShowTheNightShiftOnlyToTeamSiteOwners()
            If (BelongsToGroup("Team Site Owners")) Then
                RestrictAccess()
            End If
        End Sub
    End Class
End Namespace

The code will virtualize the Shift controller by changing the header text of the grid view to a custom text if the current user belongs to Team Site Owners group.

It also restricts the list of shifts to the “Night” shift only. The actual database contains “Day” and “Evening” shifts as well but there is nothing the user from the group “Team Site Owners” can do to see the data.

The default instance of Microsoft SharePoint Foundation is configured to execute in Minimal trust mode. Open “C:\inetpub\wwwroot\wss\VirtualDirectories\80\web.config” file in a text editor and make sure to that the trust is set to at least “Medium” or “High” level.

<trust level="WSS_Medium" originUrl="" />

Run the solution. Visual Studio will deploy the solution to your local SharePoint instance. Place the application web part on any site page and activate the logical page named “Human Resources | Shift”.

Activating logical page 'Human Resources | Shift' in the webpart created with SharePoint Factory and Code On Time

Save changes in the part editor and exit the page edit mode.

If you are the site owner then this is what you will see.

Only the “Night” shift is visible.  Also a custom message will be displayed at top of the Shift grid view.

User from 'Team Site Owners' group is effected by access control rules and virtualization. Only the 'Night' shift is visible.  Also a custom message will be displayed at top of the 'Shift' grid view.

The applications users that do not belong to the Team Site Owners group will not be affected by virtualization and access control rule.