Friday, June 15, 2012

Implicit Filters with Dynamic Access Control Rules

The property Context Fields can pass values from the current record to the lookup data view. The value is passed in the format LookupFieldName=FieldNameOfThisView as an external filter. Multiple value mappings can be specified.

If LookupFieldName matches a data field in the lookup view, then an automatic “equals” filter will be applied to the lookup. If the LookupFieldName does not match, then the application framework will not perform filtering. A developer can use the passed external filter field value to create a filter expression or business rule implementing custom filtering.

Let’s create a business rule for a lookup view that takes advantage of values passed in the Context Fields property.

Navigate to the Orders page, and select an order. Create a new order detail, and activate the lookup for ProductID. The Northwind database has 77 products. All products will be available for selection in the Products lookup.

Lookup list of all 77 products available for selection.

Let’s exclude products already associated with order details of the existing order from this view.

Start the Project Designer. In the Project Explorer, switch to the Controllers tab. Double-click on Products controller node.

Products controller selected in the Project Explorer.

Change the Handler property:

Property New Value
Handler ProductsBusinessRules

Press OK to save the controller. Double-click on OrderDetails / Fields / ProductID field node.

ProductID field of OrderDetails controller.

Change the Context Fields property:

Property New Value
Context Fields ExistingOrderID=OrderID

Press OK to save the field. On the toolbar, press Exit to close the Project Designer, and click Generate.

When complete, click on the project name, and select Develop to open Visual Studio.

In the Solution Explorer of Visual Studio, double-click on ~\App_Code\Rules\ProductsBusinessRules.cs(.vb) file.

ProductsBusinessRules file in the Code On Time web application.

Replace the existing code with the following business rule:

C#:

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

namespace MyCompany.Rules
{
    public partial class ProductsBusinessRules : MyCompany.Data.BusinessRules
    {
        protected override void EnumerateDynamicAccessControlRules(string Products)
        {
            FieldValue orderId = SelectExternalFilterFieldValueObject(
                "ExistingOrderID");
            if (orderId != null && orderId.Value != null)
                RegisterAccessControlRule("ProductID",
                    "[ProductID] in (select ProductID from [Order Details] " +
                    "where OrderID = @OrderID)",
                    AccessPermission.Deny,
                    new SqlParam("@OrderID", orderId.Value));
        }
    }
}

Visual Basic:

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

Namespace MyCompany.Rules

    Partial Public Class ProductsBusinessRules
        Inherits MyCompany.Data.BusinessRules
        Protected Overrides Sub EnumerateDynamicAccessControlRules(Products As String)
            Dim orderId As Object = SelectExternalFilterFieldValueObject(
                "ExistingOrderID")
            If (orderId IsNot Nothing AndAlso orderId.Value IsNot Nothing) Then
                RegisterAccessControlRule("ProductID",
                    "[ProductID] in (select ProductID from [Order Details] " +
                    "where OrderID = @OrderID)",
                    AccessPermission.Deny,
                    New SqlParam("@OrderID", orderId.Value))
            End If
        End Sub
    End Class
End Namespace

The business rule tries to locate the external filter field ExistingOrderID. If it is found, and the value is not null, then the business rule will register an access control rule. The access control rule will deny access to products that are matched to the “Order Details”.“ProductID” column if the column OrderID is equal to the value passed in ExistingOrderID filter field.

Save the file, and run the web application.

Navigate to the Orders page, and select an order. Note the number of order details belonging to the order.

Order Details child view displaying 3 records that belong to the selected order.

Create a new order detail. Click on (select) link in the Product Name lookup.

Product Name lookup on the New Order Details create form.

The Product lookup will open. There will be no products that are already ordered. In the example below, there are only 74 products displayed out of 77 products in the database.

Limited subset of 74 products displayed in the lookup.

No comments:

You can find more about Code OnTime Generator, Data Aquarium Framework, and other great products here.


© 2010 Code OnTime LLC. Intelligent code generation software for ASP.NET. Visit us at http://codeontime.com