Friday, January 4, 2013

Handling JavaScript Resources in Rich Client ASP.NET Applications

             Rich client application using tonnes of Javascript files are relatively new to .NET world. Most of the ASP.NET based applications rely on view creation in aspx and code behind files. User friendly client interactive applications forces the designers to move view creation and interaction logic to client browser. Earlier flash and Silverlight played a very good job in rich client Web application. Now world is moving towards HTML 5 and retirement of flash and Silverlight are nearing. As HTML 5 is becoming standard, .NET world forced to adopt it and needs to use JavaScript based thick client as front end.  Single Page Application using ASP.NET,Knockout.js,upshot.js etc are getting popular.  As more and more logic are added in client side through huge number of Javascript files, Handling of JavaScript files pose a major challange. If application is SaaS based cloud application, question becomes more complex. There are few tips  which will be helpful to handle JavaScript resources in ASP.NET based cloud application.

1. Reduce the number of JavaScript files - Always include the really needed Javascript file for a particular page. It is  unwise to globally include all Javascript for all the pages. It would be a nice architecture if you load the required Javascript files for a (ASP.NET)  page/module request  from page to  JS files mapping which is stored in common XML file. By this way,  you can centralize the needed JavaScript for each page in one place. It will improve the  maintainability of the code.

2. Minimize the size -  Normal JavaScript file contains lot of  page breaks, spaces, comments etc . They are necessary for the maintainability and debugging. but it increases the size of network transfer and performance of the application. Best way is to minimize the Javascript files by removing unnecessary  spaces,comments and line breaks. You can write your own program to trim those while application on load. Crockford created Jsmin library for this purpose in C language. There are lots of C# version of the library available in open source. Lot of  other open source library also available. These Minifier can reduce the size of the Javascript to half!.

Microsoft AJAX minifier is a command line tool which can minimize the Javascript file. It is possible to add this tool in visual studio under External tool. So that you can open a javascript file and run the tool from visual studio menu to minimize the files.


3. Bundle the  JavaScript files -  It is common to use large number of small sized JavaScript files in the application. It improves the maintainability and debugging. But browser has to make request for each JavaScript files. As number of request increases, browser round trip to server also increases. It can reduce the performance. It is always better to combine all the requested  JavaScript files to  one or couple of files and push those combined files to client. As specified in the previous point, if you have mapping between ASP.NET page name and JavaScript files,Based on requested page, you can get list of required JavaScript files , minimize each of them and combine the minimized file and return the combined file to client.

4. Version the JavaScript Resources - Always append some unique identifier with the JavaScript  It will avoid the browser cache problem. Some times, the changes in JavaScript files may not be downloaded to client browser because of older cached version of same file. By appending some Unique Identifier, especially  build version, whenever new build happens, browser will be prompted to download newer version of the file. By this way, Your support team need not instruct the customers to clear the browser cache  during every release.

5. Ability to use debug version - Make sure to turn off/on the minification and bundling option from web.config switch. It will be practically impossible to debug minified and bundled JavaScript. You need  unminified full version of JavaScript file for debugging purpose. When the code is moved to production, Javascript resources should be minified and bundled.

6. Compress the resources in IIS - Use inherant feature of IIS to compress the static resource content like Javascript files. To enable the compression, follow the steps
1. Open IIS Manager
2. Choose the site of interest.
3. Click Compression icon in right side
4. Check "Enable Static Content Compression"
This can reduce the network related traffic considerably.

7. Cache the Resources - Minification and bundling are really expensive jobs. Whenever you do minification and bundling, do it one time and cache the resources. Later on, retrieve the resources from cache.  These files can be created during first request or prebuilt files can be stored and cached before application access. Where to store the bundled and minified resources ? It is not a good idea to store the files in same virtual directory. If you store it in different folder or in memory , How to render to client.

System.Web.Hosting class in .NET provides  VirtualPathProvider class.
The VirtualPathProvider class provides a set of methods for implementing a virtual file system for a Web application. In a virtual file system, the files and directories are managed by a data store other than the file system provided by the server's operating system. For example, you can use a virtual file system to store content in a SQL Server database. You can customize this functionality so that you can store the files in altogether different folder in machine and can map the virtual path to the folder.

 8. Synchronize  data in all load balanced servers - If you use load balanced server, you can use separate server to service resources like css,images and JavaScript. Otherwise Make sure to update the minimized and bundled files in all the servers. It is good to make this process during build process instead of run time process.

Handling Bundling and Minification - ASP.NET 4.5 Way
Once innovative concepts and frameworks are out in the market, Microsoft has very good history of integrating into .NET in a developer friendly minimal coding style. Bundling and minification of the resource are not exception Manual handling of bundling and minification are discussed earlier. ASP.NET 4.5 included this feature as part of framework!.  This functionality can be achieved by minimal coding in ASP.NET 4.5.

Here is the usual way of including the JavaScript files.

<head runat="server">
    <title></title>
    <script src="../../Scripts/WebForms/DetailsView.js" type="text/javascript"></script>
        <script src="../../Scripts/WebForms/Focus.js" type="text/javascript"></script>
        <script src="../../Scripts/WebForms/GridView.js" type="text/javascript"></script>
        <script src="../../Scripts/WebForms/Menu.js" type="text/javascript"></script>
        <script src="../../Scripts/WebForms/MenuStandards.js" type="text/javascript"></script>
        <script src="../../Scripts/WebForms/SmartNav.js" type="text/javascript"></script>
        <script src="../../Scripts/WebForms/TreeView.js" type="text/javascript"></script>
        <script src="../../Scripts/WebForms/WebForms.js" type="text/javascript"></script>
        <script src="../../Scripts/WebForms/WebParts.js" type="text/javascript"></script>
        <script src="../../Scripts/WebForms/WebUIValidation.js" type="text/javascript"></script>

</head>
<body>
    <form id="form1" runat="server">
    <div>
    <asp:placeholder runat="server">
        

    </asp:placeholder>
    </div>
</form>
</body>
This code will make multiple JavaScript file request from client.Fiddler trace will show as below


You can see 10 different request from browser.  Apart from making multiple trips, total amount of data transferred is around 160 kb. Think about the scenario in which  browser made single request and gets lesser size of the returned data. That will give very good performance improvement.

Now ASP.NET 4.5 provides inbuilt support for bundling and minification of files. The core functionality of bundling and minification is found in System.Web.Optimization namespace. This feature is automatically included .

If you create the ASP.NET web form project, Use the following steps to achieve the bundling and minification functionality.

Create the Bundle

You can see the bundle creation code in BundleConfig class in the App_Start folder. The following code shows the bundle creation. You can create as many bundle as you want based on the need.This will help you to avoid unnecessary includes of unwanted JS files. Default new project created from visual studio has code to create these 3 bundles.
1.WebFormJs
2. MsAjaxJs
3. Modernizr

 public class BundleConfig
    {
        // For more information on Bundling, visit http://go.microsoft.com/fwlink/?LinkId=254726
        public static void RegisterBundles(BundleCollection bundles)
        {
            bundles.Add(new ScriptBundle("~/bundles/WebFormsJs").Include(
                  "~/Scripts/WebForms/WebForms.js",
                  "~/Scripts/WebForms/WebUIValidation.js",
                  "~/Scripts/WebForms/MenuStandards.js",
                  "~/Scripts/WebForms/Focus.js",
                  "~/Scripts/WebForms/GridView.js",
                  "~/Scripts/WebForms/DetailsView.js",
                  "~/Scripts/WebForms/TreeView.js",
                  "~/Scripts/WebForms/WebParts.js"));

            bundles.Add(new ScriptBundle("~/bundles/MsAjaxJs").Include(
                "~/Scripts/WebForms/MsAjax/MicrosoftAjax.js",
                "~/Scripts/WebForms/MsAjax/MicrosoftAjaxApplicationServices.js",
                "~/Scripts/WebForms/MsAjax/MicrosoftAjaxTimer.js",
                "~/Scripts/WebForms/MsAjax/MicrosoftAjaxWebForms.js"));

            // Use the Development version of Modernizr to develop with and learn from. Then, when you’re
            // ready for production, use the build tool at http://modernizr.com to pick only the tests you need
            bundles.Add(new ScriptBundle("~/bundles/modernizr").Include(
                "~/Scripts/modernizr-*"));
        }

Register the Bundle

Registering the bundle happens in the Application_Start method in the Global.asax file.

        void Application_Start(object sender, EventArgs e)
        {
            
            // Code that runs on application startup
            BundleConfig.RegisterBundles(BundleTable.Bundles);
            AuthConfig.RegisterOpenAuth();
        }

Use the Bundle

Here is the syntax about how to use it.

<head runat="server">
    <title></title>
 </head>
<body>
    <form id="form1" runat="server">
    <div>
    <asp:PlaceHolder runat="server">
        <%: Scripts.Render("~/bundles/WebFormsJs") %>

    </asp:PlaceHolder>
    </div>
    </form>
</body>
</html>


Scripts.Render("~/bundles/WebFormsJs") 
is the actual syntax which renders minified file.
With the minification, fiddler trace will be like this


The number of request is Minimised to one. Apart from this the total size is just 60 KB. Application  compressed and reduced the size to around 40%. This will make a big difference in internet scenario. Normal thick web client usually sends files in Megabytes and the benefit will be exponential in those cases!

The same technique can be used for CSS minification also.

Switching between Minified and Unminified Version 

During development, We need unminified and unbundled files for debugging. But during release, we may need bundled & minified code. We can't have two different code for development and release. Microsoft handles this in nice way!. To enable minification, you need to do any one of the following.

Mark the Compilation - debug to true in the web.config file

<compilation debug="true" targetFramework="4.5" />
or override the settings in global.asax with BundleTable.EnableOptimizations = true;

       void Application_Start(object sender, EventArgs e)
        {
            BundleTable.EnableOptimizations = true;
            // Code that runs on application startup
            BundleConfig.RegisterBundles(BundleTable.Bundles);
            AuthConfig.RegisterOpenAuth();
        }
If you don't do the above, Application will automatically return unbundled & unminified file for debugging purpose even with the bundling  Javascript syntax in aspx page!

Happy Coding!

Sunday, December 16, 2012

Bug in Microsoft SSRS architecture

Microsoft SQL Server Reporting services (SSRS) is one of the best reporting solution available in market. Since it is coming as free with SQL Server, Most of the companies tries to use it for Reporting solutions. For intranet based appliation, it works well. Now world is moving towards cloud. As Databases are moved to cloud and web based application are common , We need a Reporting solution with perfect 3 tier architecture. As per Microsoft documentation, SSRS is multi-tiered, with an application layer, server layer, and data layer . Since it follows three tier architecture, Any front end application like report manager, report builder or third party application can access the SSRS application layer via Http/Https connection. When the application is hosted in cloud, port for http or https alone needs to be opened.
Architecture from MSDN
Since https port alone needs to be opened, We can think SSRS as perfect solution. You can create a web application by embedding reportviewer and link to the report builder in to your application. Report viewer should  help to view the report and Report builder will be helped to design report. If you create your web application as above architecture and test it locally, It will work fine. The problem will start if you host your application in cloud. When you open the report builder and try to create a dataset, you will end up in getting the following error.

A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: Named Pipes Provider, error: 40 - Could not open a connection to SQL Server)

 
If you open the 1433 port for sql server to public, Application will work fine. What does mean? Yes. You are correct. Report builder is not a perfect 3 Tier click once application. It connects database directly from client using SQL port. If you start search the web for this issue, you can find lots of reference about the issue. Someone even created a bug in Microsoft Connect and Microsoft accepted this as a limitation and try to fix in "unknown" version in the future.

It is totally impossible to open SQL port to the universe. Now you are in real trouble. The only way to overcome the issue is to keep specific machine to access Report builder and relax firewall rule to access SQL port from that specific machine.

When raised this issue to Microsoft, they are not ready to accept it as product bug. But they are calling this as a documentation bug. But still the documentation bug was not fixed till the post is published. So If you try to use SSRS in cloud, Be aware of this issue and plan accordingly!

How to use SSRS in cloud environment? Microsoft provided a very good solution earlier and now destroying this again. Let's see about that solution in another post.


Friday, December 14, 2012

Brave New Software Products for the future

After the success of SalesForce, Software product industry started to evolve to a new dimention.World is moving to cloud. "Multitenant", "Metadata Based","Platform As Service ", "cloud" and SaaS become common household word in software industry. Every product claims that they are multitenant and meta data based. But still there is a confusion that what exactly is multitenant/metadata based cloud product. what are the "different level" of multitenancy/metadata based apps. Keep in mind that there is no industry standard for this and all the discussion are arbitrary only!

Multitenancy refers to a principle in software architecture where a single instance of the software runs on a server, serving multiple client organizations (tenants). This definition is as per wikipedia. Multitenancy concept doesn't stops at software level. It spreads to Infrastructure(IaaS), Platform (PaaS) and also Software (SaaS).

SaaS mainly consist of User facing Application (business logic/UI Layer), Background Applications like Workflow and data storage/retrieval layer etc.

PaaS is a service model in which user creates software using tools and library by the provider. Tools and library can be standard like Google Appengine or it can be ability to provide certain level of customization for their existing SaaS.

IaaS includes Virtualized Hardware Infratructure, Security, Service Management like inrfrastructure related activities.

As multitenancy spans across the above three level, degree of multitenancy also varies from low to high.

Highest degree of multitenancy is the one in which IaaS, PaaS and SaaS are completely multitenant. Each customer's application is shared by all customers.Their Infrastructure is shared by multiple customers. Their platform is also shared. Of course, customers practically won't realize any of this. Here software and data storage has to be shared by many customers. It requires highly architected, well performance tuned application development. Best example of this type is Salesforce.

Lowest degree of multitenancy is the one in which IaaS is multitenant but not others. It is like software will run in one virtual environment which will have its own datastorage. Each customer will be having different virtual environment. It is possible to run different version of source code can run for different customers.

Medium degree of multitenancy is the one in which IaaS and PaaS are multitenant and all but few areas of SaaS are multitenant. Mostly data storage may not be perfect multitenant. For example, Individual database will be allocated for each tenant in a database server.

Highest degree of multitenancy requires advanced architecture but have more operational efficiency. Lowest degree of multitenancy can be achieved by quicker app development.

There are so many advantages for customers and vendors with multitenant SaaS cloud application.

1.All the customer are in latest version - All the customers will be in latest version and everyone can utilize latest features.

2.There is no upgrade nightmare for customers.Vendor will take care of upgrades free of cost.

3.Total cost is fixed. Since it is Pay as you use model, there will be no hidden or unpredictable maintenance cost for customers.

4.There is no hardware maintenance nightmare.

5.For Vendors, they don't need to maintain number of versions of software and there is no support is required for older version.

6.For customers, they can expect near 100%  availablity of application .

7.Customers can see their issues/bugs solved quickly and updated in production system.

8.Low cost - Since application can be scaled for thosands of customers with minimum hardware infrastructure, cost will be less.


 Metadata driven architecture helps to create highly  customizable application. Perfect metadata driven application should create all UI pieces,business logic, workflows, integration with other systems throgh metadata layer.Metadata includes  business, technical, operational and environmental
information.

Next generation software products should be

1.Powerful platform which can create UI presentation, processes, and business rules using multi-tenant security.

2.Simple browser based Admin tool to define rich metadata which can define UI and behaviour of complete application. 

3.User should able to generate/configure their application without knowing any complex software language.

4.Ability to integrate the application easily  from cloud to other on-premise/cloud based applications

5. Ability to upgrade to newer version without breaking existing tenants.

6.Ability to move the application from SaaS cloud to On premise. As company grows or due to merger/acquisition, decision to maintain application in cloud or on-premise will change frequently.

7.Better usability

8.Continuous innovative new  feature  release in short period.

Now lots of start up from silicon valley started devloping these kind of innovative products in present for the better future.