ASP.NET Membership

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(8) OAuth Scopes(1) OAuth2(11) Offline(20) Offline Apps(4) Offline Sync(5) Oracle(10) PKCE(2) PostgreSQL(2) PWA(2) QR codes(2) Rapid Application Development(5) Reading Pane(2) Release Notes(179) Reports(48) REST(29) RESTful(29) RESTful Workshop(15) RFID tags(1) SaaS(7) Security(80) 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
ASP.NET Membership
Wednesday, July 10, 2013PrintSubscribe
Validation with Code Business Rules

Data integrity is a primary concern of any database application. Data constraints must exist on the database and application server level, while client-side validation will make a web app more responsive and user-friendly.

For example, consider the following screenshot of the New Order Details form. End users can select any product and enter any price, quantity, and discount. The database engine will validate the constraints of the table Order Details and raise an exception when invalid data is submitted.

The database will prevent saving of the record if the table constraints are violated.

Let’s implement a code business rule that will perform more complex validation for Order Details controller.

Configuring Fields

Start the Project Designer. In the Project Explorer, switch to the Controllers tab and double-click on OrderDetails / Fields / ProductID* (Int32) –> Products node.

ProductID field of OrderDetails controller.

Change the following:

Property Value
Copy UnitPrice=UnitPrice

Press OK to save. Next, double-click on UnitPrice* (Decimal) field node.

UnitPrice field of OrderDetails controller.

Make the following changes:

Property Value
The value of this field is calculated by a business rule expression. true
Context Fields ProductID, UnitPrice, Quantity, Discount

Press OK to save.

Configuring Business Rule

Right-click on OrderDetails / Business Rules node, and press New Business Rule.

Creating a new business rule for OrderDetails controller.

Assign the following values:

Property Value
Type C# / Visual Basic
Command Name Calculate|Insert|Update
Phase Execute

Press OK to save. On the toolbar, press Browse to generate the business rule file.

When complete, right-click on OrderDetails / Business Rules / Calculate|Insert|Update (Code / Execute) – r100 node, and press Edit Rule in Visual Studio.

Editing the rule in Visual Studio.

Replace the code base with the following:

C#:

using System;
using System.Data;
using MyCompany.Data;

namespace MyCompany.Rules
{
    public partial class OrderDetailsBusinessRules : MyCompany.Data.BusinessRules
    {
        [Rule("r100")]
        public void r100Implementation(int? orderID,
            string orderCustomerID,
            string orderCustomerCompanyName,
            string orderEmployeeLastName,
            string orderShipViaCompanyName,
            FieldValue productID,
            string productProductName,
            string productCategoryCategoryName,
            string productSupplierCompanyName,
            FieldValue unitPrice,
            short? quantity,
            float? discount)
        {
            // 1. If the collected values are not valid then do not enforce the rule.
            //    The client library will instruct the user to correct the input.
            bool success = this.ValidateInput();
            string commandName = this.Arguments.CommandName;
            string triggerFieldName = this.Arguments.Trigger;

            // 2. Reset the base price for calculation of price limits 
            //    if the product selection has changed or if an existing
            //    data row has been selected for editing
            FieldValue oldProductID = (FieldValue)this.GetProperty("Session_ProductID"); 
            if (oldProductID == null || productID.Value.ToString() != oldProductID.Value.ToString())
            {
                decimal basePrice = Convert.ToDecimal(unitPrice.Value);
                if (!triggerFieldName.Equals("ProductID"))
                    basePrice = Convert.ToDecimal(unitPrice.OldValue);
                this.SetProperty("Session_UnitPrice", basePrice);
                this.SetProperty("Session_ProductID", productID);
                if (triggerFieldName.Equals("ProductID"))
                {
                    quantity = 1;
                    UpdateFieldValue("Quantity", quantity);
                    discount = 0;
                    UpdateFieldValue("Discount", discount);
                    Result.Focus("Quantity");
                }
            }
            // 3. Adjusting base price for an existing record
            decimal originalUnitPrice = (decimal)this.GetProperty("Session_UnitPrice");
            if (originalUnitPrice == null || originalUnitPrice == 0)
            {
                originalUnitPrice = Convert.ToDecimal(unitPrice.OldValue);
                this.SetProperty("Session_UnitPrice", originalUnitPrice);
            }
            // 4. validate Unit Price field
            if (success)
            {
                decimal minPrice = originalUnitPrice;
                decimal maxPrice = originalUnitPrice * (decimal)1.05;
                success = unitPrice != null;
                if (!success)
                    Result.Focus("UnitPrice", "Please enter the price.");
                else
                {
                    decimal price = Convert.ToDecimal(unitPrice.Value);
                    success = minPrice <= price && price <= maxPrice;
                    if (!success)
                        Result.Focus("UnitPrice", "This price must be between {0:c} and {1:c}", 
                            minPrice, maxPrice);
                }
            }
            // 5. validate Quantity field
            if (success)
            {
                success = quantity != null && quantity > 0;
                if (!success)
                    Result.Focus("Quantity", "The quantity must be greater than zero.");
            }
            // Validate Discount field
            if (success)
            {
                // 6. If value > 1, then convert value to percentage
                if (discount > 1)
                {
                    discount = discount / 100;
                    UpdateFieldValue("Discount", discount);
                }
                // 7. Confirm that Discount is between 0.00 and 0.99
                success = discount != null && discount >= 0.00 && discount <= 0.99;
                if (!success)
                    Result.Focus("Discount", 
                        "The discount must be between 0.00 and 0.99 (0% - 99%).");
            }
            // 8. Wrapping Up
            if (commandName == "Calculate" || !success)
                this.PreventDefault();
        }
    }
}

Visual Basic:

Imports MyCompany.Data
Imports System
Imports System.Data

Namespace MyCompany.Rules
    
    Partial Public Class OrderDetailsBusinessRules
        Inherits MyCompany.Data.BusinessRules
        <Rule("r100")> _
        Public Sub r100Implementation(ByVal orderID As Nullable(Of Integer),
                                      ByVal orderCustomerID As String,
                                      ByVal orderCustomerCompanyName As String,
                                      ByVal orderEmployeeLastName As String,
                                      ByVal orderShipViaCompanyName As String,
                                      ByVal productID As Nullable(Of Integer),
                                      ByVal productProductName As String,
                                      ByVal productCategoryCategoryName As String,
                                      ByVal productSupplierCompanyName As String,
                                      ByVal unitPrice As FieldValue,
                                      ByVal quantity As Nullable(Of Short),
                                      ByVal discount As Nullable(Of Single))
            ' 1. If the collected values are not valid then do not enforce the rule.
            '    The client library will instruct the user to correct the input.
            Dim success As Boolean = Me.ValidateInput()
            Dim commandName As String = Me.Arguments.CommandName
            Dim triggerFieldName As String = Me.Arguments.Trigger

            ' 2. Reset the base price for calculation of price limits 
            '    if the product selection has changed or if an existing
            '    data row has been selected for editing
            If Me.GetProperty("Session_ProductID") Is Nothing OrElse
                productID.Value.ToString() <> Me.GetProperty("Session_ProductID").ToString() Then
                Dim basePrice As Decimal = Convert.ToDecimal(unitPrice.Value)
                If Not triggerFieldName.Equals("ProductID") Then
                    basePrice = Convert.ToDecimal(unitPrice.OldValue)
                End If
                Me.SetProperty("Session_UnitPrice", basePrice)
                Me.SetProperty("Session_ProductID", productID)
                If triggerFieldName.Equals("ProductID") Then
                    quantity = 1
                    UpdateFieldValue("Quantity", quantity)
                    discount = 0
                    UpdateFieldValue("Discount", discount)
                    Result.Focus("Quantity")
                End If
            End If
            ' 3. Adjusting base price for an existing record
            Dim originalUnitPrice As Nullable(Of Decimal) =
                CDec(Me.GetProperty("Session_UnitPrice"))
            If originalUnitPrice Is Nothing OrElse originalUnitPrice = 0 Then
                originalUnitPrice = Convert.ToDecimal(unitPrice.OldValue)
                Me.SetProperty("Session_UnitPrice", originalUnitPrice)
            End If
            ' 4. validate Unit Price field
            If success Then
                Dim minPrice As Decimal = originalUnitPrice
                Dim maxPrice As Decimal = originalUnitPrice * CDec(1.05)
                success = unitPrice IsNot Nothing
                If Not success Then
                    Result.Focus("UnitPrice", "Please enter the price.")
                Else
                    Dim price As Decimal = Convert.ToDecimal(unitPrice.Value)
                    success = minPrice <= price AndAlso price <= maxPrice
                    If Not success Then
                        Result.Focus("UnitPrice",
                                     "This price must be between {0:c} and {1:c}",
                                     minPrice, maxPrice)
                    End If
                End If
            End If
            ' 5. validate Quantity field
            If success Then
                success = quantity IsNot Nothing AndAlso quantity > 0
                If Not success Then
                    Result.Focus("Quantity", "The quantity must be greater than zero.")
                End If
            End If
            ' Validate Discount field
            If success Then
                ' 6. If value > 1, then convert value to percentage
                If discount > 1 Then
                    discount = discount / 100
                    UpdateFieldValue("Discount", discount)
                End If
                ' 7. Confirm that Discount is between 0.00 and 0.99
                success = discount IsNot Nothing AndAlso discount >= 0.0 AndAlso discount < 1
                If Not success Then
                    Result.Focus("Discount",
                                 "The discount must be between 0.00 and 0.99 (0% - 99%).")
                End If
            End If
            ' 8. Wrapping Up
            If commandName = "Calculate" OrElse Not success Then
                Me.PreventDefault()
            End If
        End Sub
    End Class
End Namespace

The business rule is written in C# or Visual Basic. The fields are present in the arguments of the method. Changing the data type of the argument to FieldValue allows accessing additional properties of the field.

Click Browse button on the toolbar, sign in as admin/admin123% and navigate to Customers / Order Details page.

The business rule will be engaged as soon as a new record is being entered or an existing one is modified. The business rule will react to changes to the fields specified in the Context Fields property of UnitPrice when Calculate action is raised. The field UnitPrice depends on itself. It does not matter which application field is used to trigger the Calculate action. The only field that cannot trigger the calculation is ProductID. The Context Fields of a lookup will provide filtering information for the lookup window. Any field names in the Context Fields of ProductID will make the client library treat them as context filters, which will prevent users from seeing any products in the lookup window.

Business Rules provide a true abstraction level and separation from the user interface. The business rule is not actively selecting user interface elements to collect input values, which allows flexible modification of the presentation and the rule itself. The same business rule can service any number of data controller views regardless of the view types.

There are eight distinct steps in the business rule.

1. Initial Input Validation

The client library automatically performs basic validation of the entered values. The rule declares success variable, which is used to determine if any special validation needs to be applied to the fields.

The command causing the rule to execute is stored in commandName variable. The possible values are Calculate, Insert, or Update.

The rule also makes a note of the field that has triggered the business rule. The trigger field name will be known only when Calculate action is raised. The possible triggers are ProductID, UnitPrice, Quantity, and Discount.

This is an example of a basic validation that does not require custom coding.

Basic validation performed on the client.

2. Determination of The “Base” Price

The rule will memorize the last ProductID and UnitPrice in the properties of the data view instantiated on the browser page. The base price is used to ensure that users do not enter lesser values and to prevent the price inflation by more than 5%. If the product has just been changed, then the rule will reset values of fields Quantity and Discount and set the focus on the Quantity field.

This screen shot shows the form after the product selection.

The unit price is copied from the Product.

3.  Adjusting Base Price for Existing Records

If the user is editing an existing record then the old (original) value of the UnitPrice is memorized in the data view properties.

4. Price Validation

The business rule figures the minimum and maximum price that can be entered by the user. If the price is blank, then the user is instructed to enter a value. If the price is out of range, then the user is forced to correct the problem.

This is the price validation in the form view.

Validation is performed on the unit price.

This is how the price validation is performed in the data sheet view.

Validation performed in data sheet view.

5. Quantity Validation

The rule ensures that a positive Quantity is entered.

Validation to ensure positive quantity.

6.  Automatic Conversion of Discount

The Discount column in Order Details table has the Single type. There is also a database constraint that requires the value to be between zero and one. The business rule will help the user by automatically converting the discount to a fraction of 100.

A user has entered a value greater than one in this screenshot.

Discount is converted to a percentage.

The value is automatically converted when the user leaves the field.

7. Discount Range Validation

If the end user is trying to enter a particularly high discount that remains out of range even after automatic conversion, then the validation error is displayed.

Validation is performed on Discount field.

8. Wrapping Up

The default behavior of the client library is to send the collected values to the server for processing by application. The business rule will prevent this from occurring. The business rule prevents server-side execution of Calculate action. It is also preventing server-side processing of Insert and Update if the validation has not been successful.

Saturday, July 6, 2013PrintSubscribe
How to Configure Azure Factory Project

With the release of Windows Azure, Microsoft has provided a great cloud database, storage, and computing service platform. Windows Azure offers many benefits, such as guaranteed 99.95% uptime, automatic OS and service  patching, integrated network load balancing, and easy scaling.

While the Windows Azure cloud may offer the perfect platform to deploy your next web application, you still need to build this application. This is where Code On Time’s Azure Factory comes in. All you have to do is paste in your SQL Azure database connection string, and hit Generate. In a minute, your advanced web application will start in your default browser, complete with sorting, adaptive filtering, reporting, charts, and much more. Hit Publish, and the application will be packaged. Upload the published deployment package to Windows Azure, and within minutes you’ll have your app running in the cloud.

Need to add more features and customize your app? Just make your changes in the easy to use Project Designer. While no coding is needed to make a great app, you can always open the source code in Visual Studio and change it to precisely fit your requirements.

The following article will explain how to generate and deploy an Azure Factory application. View our learning system if you need help setting up a Windows Azure account or creating a database using SQL Azure tools.

In order for the application created in this article to work properly, make sure to install Microsoft Azure SDK.

Creating the Azure Factory Project

Start the app generator, and click on Create a new web application. Select Azure Factory.

Creating a new Azure Factory project.

Enter a name, select your preferred language, and press Create.

Entering a name and specifying a language for the project.

Press Next to navigate to the Database Connection page. Click on the “…” button.

Enter your server username and password. If you already have an SQL Azure database, then enter the name in the Database field. If you don’t have a database, you can quickly create one using the web application generator. The next few steps explain how to create a sample Northwind database, include ASP.NET Membership and Roles, and add Session State management.

In the Database textbox, enter “Northwind”. Press Create to create the database.

Creating the 'Northwind' database.

In the Sample Tables dropdown, select Northwind and press Install.

Installing the Northwind database.

Under Membership section, press Add button. ASP.NET Membership will be installed in the database.

Adding ASP.NET Membership and Roles provider into the database.

By default, Azure Factory applications are configured to use two extra-small server instances in the cloud. If you use multiple instances, then Session State management must be included in the application. Under Session State, press Add. Press OK to confirm the installation.

Adding Session State management into the database.

Press OK to save the connection string. Press Next twice to get to the Reporting page.

Enabling reporting in the web app.

Check the box to enable reporting, and keep pressing Next to reach the Theme page. Select “Azure” theme.

Selecting the 'Azure' theme.

Hold down Shift key, and press Next. This shortcut will take you to the Summary page. Press the Generate button.

Wait until the generator finishes, and your default browser will open with your new web application. While the application is running on your computer, the database is located in the cloud. You can log in and start using the app immediately.

Deploying the Web App

It’s time to deploy the app to Azure. Go back to the generator, and click on the project name. Press Publish.

Publishing the web app from Code On Time generator.

When the process is complete, the publish folder will be opened and will contain two files, CloudApp.cspkg and ServiceConfiguration.cscfg.

Navigate to the Azure Portal. In the bottom left corner, press New. Select Compute | Cloud Service | Custom Create.

Creating a new cloud service in the Azure portal.

Specify a URL, check the box next to “Deploy a cloud service package”, and click on the right arrow.

Specifying a URL for the new cloud service.

Next, specify a deployment name and select the two file locations. Mark the Environment as “Staging”. Click on the check icon to start deployment.

Specifying parameters for publishing the new cloud service.

Press OK, and Windows Azure will start the deployment process. This step may take up to 15 minutes. Once the status of the deployment changes to Ready, use the SITE URL link found under DASHBOARD tab to view the app running in the cloud.

If you look at the URL, you will notice that it uses the ID of the deployment, not the requested DNS Name. This is because the deployment is a staging deployment. You can go back to the management portal, and choose Swap to change it into a production deployment. Now you can use the DNS Name you specified during creation of the hosted service.

When you are ready to deploy a new project revision, create a new staging deployment. Test the new deployment in the cloud. If everything is working as expected, then swap the virtual IP address of the staging deployment with the production one. Click Swap button at the bottom of the screen to do so.

SWAP button at the bottom of the screen will swap the staging and production environments.

When VIP swapping has finished, the previous application revision will become a staging deployment. Shut it down if you don’t need it. Continue upgrading staging deployment with the new revisions of the application, and swapping them later with production.

Tuesday, June 11, 2013PrintSubscribe
Password Recovery

Code On Time web apps using ASP.NET Membership automatically come configured with a password recovery form. This form can be opened by clicking on the Forgot your password? link on the dropdown login form.

The Forgot your password? link access the Password Recovery form.

When the user enters their User Name and Password Answer correctly, a new password will be sent to the email on file.

The Password Recovery form.

There are situations in which it may be necessary to allow users to access this form from a different location within the web app. In addition, if Custom Membership is used, the Forgot your password? link is not present. Let’s place the password recovery form in a custom user control and add this control to the home page.

Start the Project Designer. In the Project Explorer, right-click on Home / container2 node, and press New Control.

Adding a new control to the Home page.

Next to the User Control lookup, click on the New User Control icon.

Creating a new user control.

Assign a name to the user control:

Property Value
Name PasswordRecoveryForm

Press OK to save the user control. Press OK again to instantiate the user control on the Home page.

On the toolbar, press Browse to generate the user control. When complete, right-click on Home / container2 / control3 – PasswordRecoveryForm node and press Edit in Visual Studio.

Editing the user control in Visual Studio.

The file will open in Visual Studio. Replace the existing code after the <%@ Control %> element with the following:

<asp:PasswordRecovery runat="server" />

Press OK to save the file. Switch back to the browser. Notice that the Password Recovery form is placed after the Instructions text box on the Home page.

The standard password recovery form on the home page.

Note that you must configure SMTP settings in order for the password recovery email to be sent by the application.

Continue to Data View Refresh