We should use the appropriate architecture when developing ASP.net AJAX application to leverage the advantage of asynchronous data processing. The objective of this article is to give glimpse of the architecture we have to use when developing asp.net AJAX application, it also covers on the technologies we can opt for when developing various layers.
As you all aware presentation layer is hosted in web browser, and communication happens thru HTTP protocol. Unlike tradition ASP.net application where we are performing the logic of accessing the service in code behind, with ASP.net AJAX we should invoke the service layer from the java script function/java script libraries. I mentioned java script libraries as we have plenty of java script libraries available to invoke any of our service components, to name few we have JQuery, MS java script library...Etc. I call the service layer responsible for handling browser request as FAÇADE. As shown in the below picture, FAÇADE layer invokes the business logic resides in other layer to fulfill the browser request. FAÇADE would be having very minimal logic which would know which service to invoke once the request comes.
FAÇADE: It follows SOA architecture. It decouple middle layer from presentation layer. There are many advantages of having FAÇADE, as it is light weight we could even invoke FAÇADE to return different format of data which could be used for windows applications (soap) as well for web applications (JSON). We could use either WCF or web service proxy for FAÇADE. My preference goes to web service, as you don’t have dependency on .net 3.5 framework. FAÇADE should be deployed along with website, and middle layer can be in the same server or in different. Let’s take simple example on creating FAÇADE and consuming the same in web page.
Create ASP.net web service project, and add the below mentioned method.
namespace WebService1
{
/// <summary>
/// Summary description for Service1
/// </summary>
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
// To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.
[System.Web.Script.Services.ScriptService]
public class Service1 : System.Web.Services.WebService
{
[WebMethod]
public string GetServerResponse(string callerName)
{
if (callerName == string.Empty)
throw new Exception("Web Service Exception: invalid argument");
Thread.Sleep(10000);
return string.Format("Service responded to {0} at {1}", callerName, DateTime.Now.ToString());
}
}
}
If you observe, I marked the service with attribute “ScriptService” that says this service can be invoked from script and java script file was automatically generated for clients script to invoke the method at service side. Also in web.config, we have http handler to service the request in different format.
<httpHandlers>
<remove verb="*" path="*.asmx"/>
<add verb="*" path="*.asmx" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
.
.
</httpHandlers>
The specialized handler factory for .asmx requests distinguishes JSON calls made by script code from ordinary Web service calls coming from SOAP-based clients, including ASP. NET and Windows forms applications. JSON-based requests are served by a different HTTP handler (informally known as the REST handler), whereas regular SOAP calls take the usual route in the ASP.NET pipeline
We can disable SOAP clients by entering the following configuration script into the web.config file of the ASP.NET application that hosts the Web service:
<system.web>
<webServices>
<protocols>
<clear/>>
</protocols>
</webServices>
</system.web>
One more additional thing we can take care is, to have interface for the FAÇADE class to make the design consistent with the middle layer.
As I said FAÇADE can be of WCF service as well. Let’s see how we can create FAÇADE with WCF
The idea here is to get the data in JSON format. We should go for webHttpBinding for WCF application. The contract for WCF service is
// Define a service contract.
[ServiceContract(Namespace = "SimpleAjaxService")]
public interface ICalculator
{
[OperationContract]
[WebGet(ResponseFormat=WebMessageFormat.Json)]
List<string> Add(double n1, double n2);
}
One more option we can provide is adding URI in the WebGet attribute to make the service as RESTful.Something like
[WebGet(UriTemplate = "{n1},{n2}")]
Also we have attribut saying the response should be of JSON format. And the implementation class for this is
public class CalculatorService : ICalculator
{
public List<string> Add(double n1, double n2)
{
List<string> col = new List<string>();
col.Add(n1.ToString());
col.Add(n2.ToString());
col.Add(n1 + n2.ToString());
return col;
}
}
Presentation Layer:
Let’s see how we can access FAÇADE from our web page client script. The project skeleton for web application is as mentioned in following figure.
You could see the generated java script library for web service by appending JS at end of the web service URL. E.g., http://localhost:2122/FACADEService.asmx/js
Once we are done with the above step, it’s just to invoke the web service from java script in the web page. Before invoking web service we need to add script reference pointing the web service URL
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server">
<Services>
<asp:ServiceReference Path="~/FACADEService.asmx" />
</Services>
</asp:ScriptManager>
.
.
For WCF service it should be
<form id="mathForm" action="" runat="server">
<asp:ScriptManager ID="ScriptManager" runat="server">
<Services>
<asp:ServiceReference Path="service.svc" />
</Services>
</asp:ScriptManager>
</form>
With the above step, java script file is available at browser to invoke any web service method asynchronously. Let’s take we have one text box and button, upon invoking the button we need to display the server time. The HTML code for this would be
<input type="text" value="" id="MyTextBox" />
<input type="button" value="Send Request to the Web Service" id="RequestButton"
onclick="return SendRequest()" />
To invoke WCF service
<input type="text" id="num1" />
<input type="text" id="num2" />
<input id="btnAdd" type="button" onclick="return makeCall('Add');" value="Add" />
<input type="text" id="result" />
Java script function is same as invoking the web service using the complete method(including namespace) name as mentioned in below code snippet.
<script language="javascript" type="text/javascript">
function SendRequest() {
WebService1.Service1.GetServerResponse(form1.MyTextBox.value, OnComplete, OnError, OnTimeOut);
}
function OnComplete(arg)
{
alert(arg);
}
function OnTimeOut(arg)
{
alert("timeOut has occured");
}
function OnError(arg)
{
alert("error has occured: " + arg._message);
}
</script>
To invoke WCF service
function makeCall(operation){
var n1 = document.getElementById("num1").value;
var n2 = document.getElementById("num2").value;
// If user filled out these fields, call the service
if(n1 && n2){
// Instantiate a service proxy
var proxy = new SimpleAjaxService.ICalculator();
// Call correct operation on proxy
switch(operation){
case "Add":
proxy.Add(parseFloat(n1), parseFloat(n2), onSuccess, onFail, null);
break;
}
}
}
// This function is called when the result from the service call is received
function onSuccess(mathResult){
document.getElementById("result").value = mathResult;
}
// This function is called if the service call fails
function onFail(){
document.getElementById("result").value = "Error";
}
In the above we have set of other method to be fired when corresponding event happens. OnTimeout and OnError method are optional, also you can observe that the service invokes is complete name including the namespace. If you view the communication between browser and web service, it is of simple JSON format.
For Data access purpose, I would prefer to use entity framework to get the database operations. Once we are done with that we would need separate libraries where we can keep all our business logic which get installed along web application, and which get called from service. This in turn would connect to database access as we do for traditional windows or web applications.
The overall flow would be something like
Unlike traditional application, with asp.net MVC we can load only the content place holder of child pages rather than loading the complete page.MVC pattern in web application has been there quite long time, Microsoft understand the need of MVC as part of new project creation where the set of standards are drawn.
ASP.net MVC can be available either by installing Web Platform Installer 2.0 on top of VS2008 or with VS2008 team system. Its freeware and can be downloaded with the following link
Let’s create new ASP.net MVC application and go over one by one of the created files.
Select ASP.net MVC2 web application project template once we click on new project.
Once done with above step, it asks whether to create test project for web application or not. Select the appropriate option and proceed further. I had chosen not to have test project. IDE creates set of files which would be placed in appropriate directory.
Here is the need of having each file/folder
Content: where we will place all style sheet files, java script files, and images (if any). This is kind of repository used to store static data.
Controllers: These are the classes having minimum logic that knows which view or model to invoke when the request came from browser. The URL is tightly bound to controller action. When typing URL, it is not page request rather it is particular action method request in controller. Each action is associated with method in corresponding controller. Which controller to be invoked for given URL is defined in routing table available in Global.asax file.
Global.asax: It is responsible for mapping URL to controller action. All the URLs should have action name prefixed with corresponding controller name. If you see all items are optional. Also have default values specified. If any of the items is not specified it takes controller as “Home” and action name as “Index”.
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
Model: This is backbone for all application logic. It can have business logic, data access logic..Etc. Model is invoked from controller. For data applications it could of ADO.net Entity data model, typed data set, LINQ to SQL classes, or custom classes.
Views: Views are returned depending on the controller action. All views naming has to follow the convention. This is having markup along with content which get returned back to the browser. Under this folder, we have “shared” folder meant to have resource shared by all the views. We would be having master page under this folder.
Scripts: All java script libraries are copied under this location. This includes jQuery library, jQuery validation, and Microsoft Ajax library.
Web.config: we have two sets of configuration file. View folder’s web.config file is used to enable/disable validation to take place after controller process the logic.
Flow of events
When we run the application, first event get triggered is “Application_Start()” in Gobal.asax file. This would route the request to appropriate controller using RouteCollection object. Once controller receives the request, which performs minimal logic and Invoke model for any business logic and return view to the browser. View can have HTML user controls. If you see the master page, you could see the links which is having comprehensive details about which controller, action item to invoke.
<%= Html.ActionLink("Home", "Index", "Home")%>
In the above link, first item says the name that would be shown in the web browser. Second item is nothing but the action link available inside the controller. Third item is the controller which the request is sends to.
In the page, if we observe closely every time we click the link, only intended content is loading in the page rather than loading the complete page. Let’s say we have to refresh price information for every 10 seconds asynchronously, we can either do it with asynchronous calls to web service or invoking Ajax call to controller action item using JSON object of JQuery library.
Loading data using JQuery
Most of the times, we need to invoke action item at server for performing the action.Lets take we need to send a message once user clicks on submit button. For this to happen asynchronously without screen flickering, we can opt for JQuery. Here are the steps to invoke ajax call using jQuery with the default created MVC application.
Add content place header in the master page so that we can write all java script functions in the child pages inside this content place holder. Also add script file “jquery-1.4.1.min-vsdoc.js” to the master page.
<%@ Master Language="C#" Inherits="System.Web.Mvc.ViewMasterPage" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<script src="../../Scripts/jquery-1.4.1.min-vsdoc.js" type="text/javascript"></script>
<script src="../../Scripts/jquery.validate.min-vsdoc.js" type="text/javascript"></script>
<asp:ContentPlaceHolder ID="HeaderContent" runat="server" />
<title></title>
<link href="../../Content/Site.css" rel="stylesheet" type="text/css" />
</head>
When designing views, I always urge to go for simple HTML controls. For this scenerio lets assume we added one button, and on click of the button we want to invoke method in controller, and the returned result should be displayed in the label. Add the following four items into the view which inclues two input controls, the values of same would be send to the server.
<input id="name" type="text" />
<input id="comment" type="text" />
<input id="submit" type="submit" value="Submit"/>
<div id="status" ></div>
Also add script in the view under header content place holder.
<asp:Content ID="aboutTitle" ContentPlaceHolderID="HeaderContent" runat="server">
<script type="text/javascript">
$(document).ready(function() {
$("#Submit1").click(function() {
var name = $("#name").attr("value");
var comment = $("#comment").attr("value");
$.ajax(
{
type: "POST",
url: "/Home/Submit",
data: "author=" + name + "&comment=" + comment,
beforeSend: function() { $("#status").text("processing..."); },
success: function(result) {
if (result.success)
$("#status").text(result.message);
;
},
error: function(req, status, error) {
$("#status").text("Sorry! We could not receive your feedback at this time.");
}
});
});
}); </script>
</asp:Content>
If you observe, we added button click event script after page got loaded at the browser side. JQuery is very powerful, and Microsoft is fully supporting this techonogly. You can recognize jQuery as an instance of the Builder design pattern. The pattern recommends separating the construction of a complex object from its representation. You use an internal helper object as the builder and isolate in that helper all the required building logic. In this way, the constructor focuses on the expected behavior to provide the internal implementation and logic. The ajax function is the builder of the jQuery object.
Ajax function expects five parameters. First, is the kind of operation. Second is URL, in our case it’s “/controllername/actionitem”. Third, data item which is of JSON format. Fourth, says which funciton to be invoked once the function returns successfully. Fivth for any failure what need to be displayed in the browser.
All the controls are accessed using $(“#submit”), which would read as document.getelementbyid(“submit”). All the statements should end with semicolon. Once done with the client side, we should add the functionality at controller side. As URL mentioned is “/Home/Submit”, lets open HomeController add method “Submit” which would have return type as action result. Which would allow us to retun json object.
public ActionResult Submit(string author, string comment)
{
// add data processing logic
System.Threading.Thread.Sleep(10000);
return Json(new { success = true, message = "Thank you "+author+"! We value your feedback." });
}
I kept the current thread to sleep for sometime so that user distinguishes the delay at browser side. Also note that the parameter we are sending is easily be captured at controller side by just specifying the same parameter name as at the view side script.
When we run the application, it would be shown as the below screenshot
Once done, the status would be turned as shown below
In this you could see there is no screen movement nor no flickering of the page. The same way you could return custom control from the controller and can be added in the dom object dynamcally in the views.
The new control introduced for using Deep Zoom option from ASP.net web application. It is very easy to use.
For this to work, you need to have Deep Zoom Composer along with Azax Control tool kit. You can download Deep Zoom composer from the following location
and Ajax control tool kit from the following location
http://ajaxcontroltoolkit.codeplex.com/
First step is creating deep zoom image using DeepZoom composer
Steps
· Click on new project
· Click on compose
· Select the image from bottom pane
· Drag the image to the top pane
· Make the image to the full screen
· Click on export
· Click custom, enter the name and give the quality to 100
· Click on export button
Next step, building the website for making using of the deep zoom image
Steps
· Create new empty website
· Refer AjaxControlTookKit.dll using add reference
· Add created folder(e.g., dzc_output_files) and output file(dzc_output.xml) of the Deep Zoom Composer output
· Add the following piece of code to webpage, where source file referred to .xml file·
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default"%>
<%@ Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="ajaxkit" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<ajaxkit:ToolkitScriptManager CombineScripts="false" ID="abc1" runat="server"></ajaxkit:ToolkitScriptManager>
<ajaxkit:Seadragon id="seadragon1" runat="server" Height="200px" Width="200px" SourceUrl="dzc_output.xml"></ajaxkit:Seadragon>
</div>
</form>
</body>
</html>
For more info see the following clip
http://channel9.msdn.com/posts/jsenior/Seadragon-Ajax-Control-Quick-Start-Guide/
The star schema (sometimes referenced as star join schema) is the simplest style of data warehouse schema. The star schema consists of a few fact tables (possibly only one, justifying the name) referencing any number of dimension tables. The star schema is considered an important special case of the snowflake schema.
A snowflake schema is a logical arrangement of tables in a multidimensional database such that the entity relationship diagram resembles a snowflake in shape. Closely related to the star schema, the snowflake schema is represented by centralized fact tables which are connected to multiple dimensions. In the snowflake schema, however, dimensions are normalized into multiple related tables whereas the star schema's dimensions are denormalized with each dimension being represented by a single table. When the dimensions of a snowflake schema are elaborate, having multiple levels of relationships, and where child tables have multiple parent tables ("forks in the road"), a complex snowflake shape starts to emerge. The "snowflaking" effect only affects the dimension tables and not the fact tables.
|
SSIS 2008 |
SSIS 2005 |
|
Scripting is changed to VSTA(Visual Studio Tools Application), and has support of C# and VB.net |
Scripting is done thru VSA(Visual Studio for Application), and has support of only C# |
|
Web reference at data flow level |
Web reference only at control flow level. |
|
Look up component uses cache connection manager. Caching is preserved in in-memory/file system (raw format) and is available till the package get completes. |
Look up component uses OLEDB connections. Cached data would be available till the current iteration completes. |
|
New transform is introduced called “Cache transform” |
It’s not available. |
|
SSIS engine is scaled up for multiple processors |
It’s not available. |
|
New command “Merge” incorporated in newer release. To goal of this command is to synchronize two tables/views |
It’s not available. |
|
Capturing changes in database or table or view level. At table level, it stores all the changes at the row level. |
It’s not available. |
|
|
|