Web Application Generator

Labels
AJAX(112) App Studio(9) 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(178) 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(184) 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(3) 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
Web Application Generator
Friday, March 9, 2012PrintSubscribe
Using ConnectionStringSettingsFactory in “Database per Tenant” Apps

Multi-tenant web applications can be constructed using one of the two methods:

  • Tenants co-exist in the same database. Data is segregated based on the user identity.
  • Each tenant has a private database.

Code On Time web applications offer excellent support for multi-tenant data segregation.

Let’s discuss how to implement a multi-tenant application with private databases.

Internet users arrive to your web application protected with ASP.NET Membership. If the user is not authenticated then there is no way to know, which private database is the final destination for this user. Therefore you either need to implement a single database of user accounts (for example an ASP.NET Membership database) or rely on the elements of the user name (for example the domain portion of the email address) to authenticate the user.

The second solution is more complex when it comes to implementing the user authentication. We will consider the first scenario and assume that the main database of the application has ASP.NET Membership installed already. Follow instructions at http://codeontime.com/learn/sample-applications/northwind to create an application with the membership feature.

The main application database will have the application tables and views. We will call it a “master” database. You will develop your application using the master database. Create additional databases with the same schema but do not include the membership infrastructure in them.

Private Database Derived From DNS Records

Deploy your application. Create CNAME records in the DNS configuration of your Internet domain for each client that must have a private database. Point the CNAME record of each client to the name of your web application. Instruct your clients to sign in the application using their dedicated domain name defined in the CNAME record.

For example, if your main application name is myapp.contoso.com then a client with a dedicate database can access your application as clientname.contoso.com. Also make sure that the name of the master database is myapp.constoso.com and the private database names for the clients use the format clientname.contoso.com.

Unauthenticated users will be authenticated against the master database membership. If you do nothing else then the authenticated users will see the contents of the master database while navigating through the application pages.

Implement the following class in your application to redirect authenticated users to the private database.

C#:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Configuration;
using System.Data.SqlClient;
namespace MyCompany.Data
{
    public partial class ConnectionStringSettingsFactory
    {
        protected override ConnectionStringSettings CreateSettings(string connectionStringName)
        {
            ConnectionStringSettings settings = base.CreateSettings(connectionStringName);
            // if the user is not authenticated then use the default database
            if (HttpContext.Current.User.Identity.IsAuthenticated &&
                HttpContext.Current.Request.Url.Host.Contains("contoso.com"))
            {
                SqlConnectionStringBuilder csb = 
                    new SqlConnectionStringBuilder(settings.ConnectionString);
                csb.InitialCatalog = HttpContext.Current.Request.Url.Host;
                settings = new ConnectionStringSettings(null, csb.ToString(), 
settings.ProviderName); } return settings; } } }

Visual Basic:

Imports Microsoft.VisualBasic
Imports MyCompany.Data
Imports System.Data.SqlClient

Namespace MyCompany.Data
    Partial Public Class ConnectionStringSettingsFactory
        Protected Overrides Function CreateSettings(
            connectionStringName As String) As System.Configuration.ConnectionStringSettings
            Dim settings As ConnectionStringSettings = 
MyBase.CreateSettings(connectionStringName) If (HttpContext.Current.User.Identity.IsAuthenticated AndAlso HttpContext.Current.Request.Url.Host.Contains(".contoso.com")) Then Dim csb As SqlConnectionStringBuilder = New SqlConnectionStringBuilder(settings.ConnectionString) csb.InitialCatalog = HttpContext.Current.Request.Url.Host settings = New ConnectionStringSettings(Nothing, csb.ToString(),
settings.ProviderName) End If Return settings End Function End Class End Namespace

This code inspects the name of the host specified in the URL of the current request. If the authenticated user is trying to access the production deployment and “*.contoso.com” is detected in the host name then the code will create a database-specific connection string and change the database name to the name of the host.

Our example uses Microsoft SQL Server database. That is why we are creating SqlConnectionStringBuilder class instance. Use the class that matches your back-end database. The name of the SQL Server database is specified in InitialiCatalog property. Implementations of connection string builder for other database engines may use a different property for the same purpose.

If your clients do have a web presence then you can instruct them to create their private CNAME Records that point to your application. Make sure to use the client’s CNAME Record as the name of the private database instance. Your clients will be able to access your web application as myapp.clientdomain.com where “clientdomain” is the client’s own domain name.

Private Database Derived From User identity

You can also implement a table in the master database that will associate the user accounts with the private databases available in the app. This table will effectively play the role of the DNS for your own application. Users will access the application via the same URL.

create table UserDatabases
(
    UserName varchar(50),
    DatabaseName varchar(50),
    primary key (UserName, DatabaseName)
)

The following code will lookup the UserDatabases table for authenticated users and adjust the connection string accordingly.

C#:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Configuration;
using System.Data.SqlClient;
namespace MyCompany.Data
{
    public partial class ConnectionStringSettingsFactory
    {
        protected override ConnectionStringSettings CreateSettings(string connectionStringName)
        {
            ConnectionStringSettings settings = base.CreateSettings(connectionStringName);
            // if the user is not authenticated then use the default database
            if (HttpContext.Current.User.Identity.IsAuthenticated)
            {
                SqlConnectionStringBuilder csb =
                    new SqlConnectionStringBuilder(settings.ConnectionString);
                using (SqlConnection connection = new SqlConnection(settings.ConnectionString))
                {
                    connection.Open();
                    SqlCommand command = connection.CreateCommand();
                    command.CommandText =
                        "select DatabaseName from UserDatabases where UserName=@UserName";
                    SqlParameter p = command.CreateParameter();
                    command.Parameters.Add(p);
                    p.ParameterName = "@UserName";
                    p.Value = HttpContext.Current.User.Identity.Name;
                    csb.InitialCatalog = Convert.ToString(command.ExecuteScalar());
                }
                csb.InitialCatalog = HttpContext.Current.Request.Url.Host;
                settings = new ConnectionStringSettings(null, csb.ToString(), 
settings.ProviderName); } return settings; } } }

Visual Basic:

Imports Microsoft.VisualBasic
Imports MyCompany.Data
Imports System.Data.SqlClient

Namespace MyCompany.Data
    Partial Public Class ConnectionStringSettingsFactory
        Protected Overrides Function CreateSettings(
            connectionStringName As String) As System.Configuration.ConnectionStringSettings
            Dim settings As ConnectionStringSettings =
                MyBase.CreateSettings(connectionStringName)
            If (HttpContext.Current.User.Identity.IsAuthenticated) Then
                Dim csb As SqlConnectionStringBuilder =
                    New SqlConnectionStringBuilder(settings.ConnectionString)
                Using connection As SqlConnection =
                        New SqlConnection(settings.ConnectionString)
                    connection.Open()
                    Dim command As SqlCommand = connection.CreateCommand()
                    command.CommandText =
                        "select DatabaseName from UserDatabases where UserName=@UserName"
                    Dim p As SqlParameter = command.CreateParameter()
                    p.ParameterName = "@UserName"
                    p.Value = HttpContext.Current.User.Identity.Name
                    csb.InitialCatalog = Convert.ToString(command.ExecuteNonQuery())
                End Using
                csb.InitialCatalog = HttpContext.Current.Request.Url.Host
                settings = New ConnectionStringSettings(Nothing, csb.ToString(),
                    settings.ProviderName)
            End If
            Return settings
        End Function
    End Class
End Namespace

Notice that we are using the native ADO.NET classes that are specific to SQL Server: SqlConnection and SqlCommand. Code On Time web applications can take advantage of SqlText class that wraps the ADO.NET components in a compact database-independent implementation. The class is the component of the framework of the generated web application and takes advantage of ConnectionStringSettingsFactory. We have to use the native ADO.NET classes to prevent the re-entrance in the ConnectionStringSettingsFactory. Adjust the sample with the native ADO.NET classes that match your database backend if you are not programming with Microsoft SQL Server.

Friday, March 9, 2012PrintSubscribe
Sakila Sample Database

A majority of examples rely on the Northwind sample database available for Microsoft SQL Server.

If your backend database is MySQL, then try Sakila sample database instead.

Getting MySQL on Your Computer

Download and install the MySQL Installer for Windows at http://dev.mysql.com/tech-resources/articles/mysql-installer-for-windows.html.

If you already have MySQL installed, then you can skip the above step.

By default, Sakila database comes with the MySQL installation. If you do not have the sample database, then you can download the database scripts at http://downloads.mysql.com/docs/sakila-db.zip.

Creating a Web Application

Run Code On Time web application generator and create a new Web Site Factory project.

Create Web Site Factory project in Code On Time web application generator

Give this project the name of “Sakila” and select the programming language of your choice (C# or Visual Basic.NET).

Selecting Name and Language of new web application project

Click Create to create the project. Press Next to reach the Database Connection page.

Change the Data Provider to “MySql.Data.MysqlClient” and press the button next to the Connection String string field.

Choosing MySQL data provider in web application generator

On the MySQL Connection page, enter your connection string settings. If you installed MySQL locally, enter:

Server Name localhost
User Name root
Password [Your Password]
Database Sakila

Entering MySQL Connection information in Code On Time generator

Press Next until you reach the Authentication and Membership page. MySQL can automatically install support for ASP.NET Membership in your database. Just check the first box on the page to enable membership support.

Enable ASP.NET Membership in Code On Time web application generator

Press Next until you reach the Themes page. Select “Vantage” theme.

Vantage theme in Code On Time web application generator

Hold down Shift key and press Next. This shortcut is available on any page of the web application generator wizard, and will skip to the Summary page.

Summary page in Code On Time generator

Click Generate to start the code generation.

A web browser window will open up when code generation has been completed.

Start using and customizing your own Sakila sample.

'Sakila' web application created with Code On Time

You can reference the same database in other projects whenever you need.

The next screenshot shows the built-in membership manager in an application created from MySQL database.

Code On Time Membership Manager in MySQL web application

Friday, March 9, 2012PrintSubscribe
Northwind Sample Application

Many of Code On Time tutorials are using Northwind sample database created by Microsoft to illustrate concepts of database design and implementation with Microsoft SQL Server.

The database is somewhat outdated and does not reflect the latest advancements in Microsoft SQL Server features and capabilities. Nevertheless, it provides a perfect dataset to illustrate the concepts of code generation.

We have bundled the script creating the Northwind sample database with the code generator. The script can be used to create a sample dataset for Microsoft SQL Server 2005, 2008, and SQL Azure.

Please follow these instructions if you want to create your own Northwind database sample.

Getting SQL Server on your Computer

Download and install Microsoft SQL Server Express edition if you have not done so already. You can download the server along with other free development tools using Microsoft Web Platform Installer, which makes the download and installation process extremely simple and pain-free. It can be downloaded at http://www.microsoft.com/web/downloads/platform.aspx.

If you have a retail or development version of Microsoft SQL Server, then this step is not needed.

If you are developing with other types of databases, such Oracle, DB2, MySQL, Microsoft Access, then getting Microsoft SQL Server Express installed will still help to get started with Code On Time, as most of the learning resources use this server. Generated web applications use a provider-independent model to access data. It means that there is no code specific to Microsoft SQL Server in the generated application framework. If your back-end database server is Oracle 11g, then exactly the same code will be generated.

Creating a Database

Run Code On Time and start creating a new Web Site Factory project.

Create a Web Site Factory Project in Code On Time web application generator

Enter project name and choose your programming language (C# or Visual Basic.NET):

Name and Language of new Project in Code On Time web app generator

Click on the  Next button to advance to the Database Connection page of the project wizard.

Click the button next to the Connection String field to open the connection configuration window.

Configuration of database connection string to SQL Server

If you just have installed Microsoft SQL Server Express Edition on your computer then enter the following text in the Server field :

.\SQLExpress

The dot in front of “\SQLExpress” indicates that you are connecting to your own computer.

If you already have a database server or working with SQL Azure, then enter the actual server name or IP address.

Enter Northwind in the Database field and click Create button to create a blank database. You should see a message stating that the database has been created successfully.

Select Northwind in the drop down under Sample Tables and click Install button. You will notice the activity log displaying various SQL statements executed against the database. You will be notified when the process completes.

Install Northwind sample table in SQL Express

Optionally, you can click Add button under Membership section to add support for ASP.NET Membership in your database. This option is not available for DotNetNuke Factory projects.

Azure Factory project offers additional section to configure session state support for multi-server deployment.

Wait for membership installation to complete and click OK button to save the settings.

Press the Next button until you reach the Themes page. Select the Modern theme.

Modern theme for Code On Time web applications

Hold down shift, and press Next. This is a shortcut that can be used in any part of the generator wizard to skip to the Summary page.

Summary page of Code On time web application generator

Click Generate to start the code generation.

A browser window will open up when code generation has been completed.

Start using and customizing your own Northwind sample.

Generated Northwind sample web application

You can reference the same database in other projects whenever you need.

Take a quick feature tour to learn more about web applications created with Code On Time.