How To Operate Multiple Customer Sites In One Application
By Eliyahu Goldin
Last edited December 24, 2006
It is quite a common scenario when the same web application has to represent multiple customer sites. On example is a hosted medical practice management system. Every practice subscribed for the service has its own presence on the web. It has a distinct set of customized parameters such as practice name, contact details, working hours and, most important, a separate practice database. The same host application has to distinguish between the practices and connect the customers to their environment.
If the number of the customer is limited to several dozens, it is easy to maintain the customer list in an XML file. Optionally, the file can contain a scheme enforcing only correct XML elements. Below is an example of a file with the XML schema and 2 customer records.
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE Customers [
<!ELEMENT Customers (Customer*)>
<!ELEMENT Customer (CustomerSupport?,DBConnection?)>
<!ELEMENT CustomerSupport (Hours+)>
<!ELEMENT Hours EMPTY>
<!ELEMENT DBConnection EMPTY>
<!ELEMENT DefaultDBCredentials
EMPTY>
<!ATTLIST Customer
Id ID #REQUIRED
Description CDATA #REQUIRED
>
<!ATTLIST CustomerSupport
Email CDATA #IMPLIED
Fax CDATA #IMPLIED
Phone CDATA #IMPLIED
TimeZone CDATA #IMPLIED
>
<!ATTLIST Hours
Name CDATA #IMPLIED
Time CDATA #IMPLIED
>
<!ATTLIST DBConnection
Server CDATA #REQUIRED
Authentication (Sql|Windows) "Windows"
Database CDATA "CliniFlow"
Username CDATA #IMPLIED
Password CDATA #IMPLIED
>
]>
<Customers>
<Customer Id="p1" Description="Practice1 Portal">
<CustomerSupport Email="support@practice1.com" Fax="234.567.8888" Phone="234.567.9999" TimeZone="EST">
<Hours Name="Sun-Thu" Time="9:00 - 18:00" />
<Hours Name="Fri" Time="9:00 - 13:00" />
</CustomerSupport>
<DBConnection Server="123.123.123.123" Authentication="Sql" Database="PracticeDB" />
</Customer>
<Customer Id="p2" Description="Practice2 Portal">
<CustomerSupport Email="support@practice2.com" Fax="345.987.6666" Phone="345.987.5555" TimeZone="PST">
<Hours Name="Mon-Fri" Time="9am - 5pm" />
</CustomerSupport>
<DBConnection Server="55.66.77.88" Authentication="Sql" Database="PracticeDB" />
</Customer>
</Customers>
Customers have to supply their Id in the URL query
parameter:
The application gets the id and sets the customer information. The following code is a part of the application logon page. The code assumes that the customer records reside in the file Customers.xml in the application root directory. The page contains server-side html controls for customer description, email address, phone and fax numbers, time zone and a datagrid for support hours.
protected void Page_Load(object
sender, EventArgs e)
{
string
customerId;
// get
customer data
if (!String.IsNullOrEmpty (this.Request.Params["id"]))
customerId = this.Request.Params["id"];
if (!this.IsPostBack)
{
setupCustomer(customerId);
}
}
private void setupCustomer(string
customerId)
{
System.Xml.XmlDocument
doc = new System.Xml.XmlDocument();
doc.Load(String.Format("{0}\\{1}", this.Request.PhysicalApplicationPath,
"Customers.xml"));
System.Xml.XmlElement
custNode = doc.GetElementById(customerId);
if
(custNode == null)
throw
new System.Xml.XmlException("Customer info not found");
// customer
info found, get parameters
this.lblCustomerDescription.InnerText
= custNode.Attributes["Description"].Value;
this.Session["CustomerDescription"] =
lblCustomerDescription.InnerText;
System.Xml.XmlElement
custSupportNode = custNode.FirstChild as
System.Xml.XmlElement;
this.lblEmail.InnerText
= custSupportNode.Attributes["Email"].Value;
this.lblPhone.InnerText
= custSupportNode.Attributes["Phone"].Value;
this.lblFax.InnerText =
custSupportNode.Attributes["Fax"].Value;
this.lblTimeZone.InnerText
= custSupportNode.Attributes["TimeZone"].Value;
System.Xml.XmlNodeList
hourNodes = custSupportNode.ChildNodes;
this.dgHours.DataSource
= hourNodes;
this.dgHours.DataBind();
System.Xml.XmlElement
dbConnectionNode = custNode.ChildNodes[1] as
System.Xml.XmlElement;
string
server = dbConnectionNode.Attributes["Server"].Value;
string
database = dbConnectionNode.Attributes["Database"].Value;
string authentication =
dbConnectionNode.Attributes["Authentication"].Value;
string
connectionString = String.Format("Server={0};Database={1}", server,
database);
if
(authentication == "Windows")
connectionString += ";Integrated
Security=SSPI";
this.Session["ConnectionString"] = connectionString;
}