Angles of AngularJS, Part-2

Tags

, , , , , , , , , , ,

Part 2 – Extending AngularJS to make it more simple and dynamic

In previous article we talked about some boilerplate code and issues that each developer has to face to work with Angular implementation and we also worked to abstract these common work into base services and controllers to come over these limitations. The main benefit of this approach is we can have core feature implementation of application in base so that its easily available to developer wherever they want.

Following were the key benefits we achieved so far

  1. Developer don’t have to inject any dependencies explicitly
  2. Common services can be made available anywhere required using ServiceLocator pattern implementation. That will reduce the time and effort of defining dependencies all over the application.
  3. Since core logic is inside the base classes, developer forced to adhere to application standards rather than implementing it their own way.


By the end of this article we will have achieve

  1. Loading Services on demand from server (lazy-loading)
  2. Simplifying components development similar to controller and services we did in last part

It can be a long talk, if I try to explain need of every design element, hence I’m going to keep the discussion to the point. Otherwise you can just download the source code and start playing around with it to get to know it deeper and even extend it further to make to work for your design the way you want.

Loading Services on demand from server (lazy-loading)

Generally small applications don’t really have to worry about this feature, you can just make sure all of your services are loaded at the page load. If your application is huge with lots of services being injected, then it makes total sense to have this implementation.

In previous article, we worked together to implement ServiceLocator that act as service provider for all over the application needs. This approach going to help us to implement lazy loading of any service form server easily.

Here is the example of service implementation before applying lazy loading of Service1 file from server with our previous work.

    class Service1 extends BaseService {
        GetItems(): angular.IPromise<string[]> {
             return this.Http().get("/api/products");
        }
    }
    class ServiceLocator extends BaseService {
        Service1(): Service1 {
             return this.Injector().get<Service1>("Service1");
        }
    }
    class HomeController extends BaseController<IHomeScope>{
        Init(): void {
             this.Scope.Items = ["I", "was", "loaded", "synchronously"];
             this.Services().Service1().GetItems()
                       .then((result) => {
                             this.Scope.Items = result.data;
             });
        }
    }

There are many ways to load files from servers, here I’m going to use ocLazyLoad library. Let’s add Load method to BaseService that will take care of loading the service from the server. This Load method will take the service name which also depicts the service file name and tells to ocLazyLoad library to load it from location /apps/services. You can use the path from your application directory structure.

    protected Load(service: string): ng.IPromise<any> {
           var lazy = this.Injector().get("$ocLazyLoad") as oc.ILazyLoad;
           return lazy.load("/apps/services/" + service + ".js")
                      .catch((reason) => {
                          throw service + " " + reason.description;
            });
    }

If you notice loading file from server is async process that means we cannot perform Service1().GetItems() call anymore, because on accessing Service1() method we first have to load file from server then only developer should be able to access service in their implementation.


Workaround to this is now have to get the action from the caller and execute it only once promise completes. Lets add helper method Invoke that will call our Load method and also handle the promise to execute action.

    protected Invoke<T, U>(service: string, action: (service: T) => ng.IPromise<U> | U): ng.IPromise<U> | U {
          return this.Load(service)
                     .then<U>((): ng.IPromise<U> | U => {
                          return action(this.Injector().get<T>(service));
          });
    }

Putting this all together out BaseService, ServiceLocator and HomeController code showed above will finally looks like

    abstract class BaseService {
        static $inject = ["$http", "$rootScope", "$injector"];
        private _http: angular.IHttpService;
        private _rootScope: angular.IRootScopeService;
        private _injector: angular.auto.IInjectorService;

        constructor(http: angular.IHttpService, rootScope: angular.IRootScopeService, injector: angular.auto.IInjectorService) {
              this._http = http;
              this._rootScope = rootScope;
              this._injector = injector;
              this.Init.bind(this);
              this.Init();
        }

        Init(): void { }

        Http(): angular.IHttpService {
              return this._http;
        }
        RootScope(): angular.IRootScopeService {
              return this._rootScope;
        }

        protected Injector(): angular.auto.IInjectorService {
              return this._injector;
        }

        protected Load(service: string): ng.IPromise<any> {
              var lazy = this.Injector().get("$ocLazyLoad") as oc.ILazyLoad;
              return lazy.load("/apps/services/" + service + ".js")
                         .catch((reason) => {
                                throw service + " " + reason.description;
              });
        }

        protected Invoke<T, U>(service: string, action: (service: T) => ng.IPromise<U> | U): ng.IPromise<U> | U {
              return this.Load(service)
                         .then<U>((): ng.IPromise<U> | U => {
                               return action(this.Injector().get<T>(service));
              });
        }
    }
    class HomeController extends BaseController<IHomeScope>{
        Init(): void {
              this.Scope.Items = ["I", "was", "loaded", "synchronously"];
              this.Services().Service1((service) => {
                    service.GetItems()
                           .then((result) => {
                                 this.Scope.Items = result;
              })});
        }
    }

Now you can see without having to do much code change we achieved to load service file on demand.

TypeScript Decorators

Before moving to our next topic for components, I want to add small thing to make it more interesting. Since components are little tricky to implement the way we have implemented services and controller, Component is mixture of both and has more capabilities to it.

That is where TypeScript decorator feature will help us to simplify defining components and minimize the coding efforts related to it. The reason I’m going to talk about TypeScript Decorator is because it adds more value to the JavaScript generation and runtime object creation. I recommend you to read about how decorators works before reading any further.

Now that you know what it does, one can easily think of its usage with respect to AngularJS. We haven’t really talked before how you register any objects in Angular to make it work with framework.

    class HomeController extends BaseController<IHomeScope>{
       . . . 
    }
    angular.module("portal").controller("HomeController", HomeController);

Let’s create decorator to handle that as well so that developer doesn’t really have to worry about registering it in Angular.

    function Service(name: string) {
         return (target: Function) => {
            angular.module("portal").service(name, target);
        };
    }

    function Controller(name: string) {
        return (target: Function) => {
            angular.module("portal").controller(name, target);
        };
    }

Now this can be used on any service and controller we want to registered with our angular module.

    @Service("Service1")
    class Service1 extends BaseService {
        GetItems(): angular.IPromise<string[]> {
              return this.Http().get("/api/products");
        }
    }

    @Service("ServiceLocator")
    class ServiceLocator extends BaseService {
         Service1<T>(action: (service: Service1) => ng.IPromise<T> | T): ng.IPromise<T> | T {
                 return this.Invoke("Service1", action);
         }
    }

    @Controller("HomeController")
    class HomeController extends BaseController<IHomeScope>{
         . . . 
    }

That’s it; amazingly, the decorator will take care of registering your functions at runtime. Basically we have pretty much isolated Angular dependencies from developer’s hand.

Simplifying components / directives

Let’s talk about components (and directives) in AngularJS and see what area of it we can improvise similar to what we did for Controllers and Services. Below is simple snippet of how components defined normally.

    interface IMyComponentScope extends IScope {
        Items: string[];
    }

    angular.module('portal').directive("MyComponent", function () {
        controller.$inject = ["$scope", "Service1"];
        var controller = function ($scope: IMyComponentScope, Service1: Service1) {
        
              $scope.Items = ["I", "was", "loaded", "synchronously"];
              Service1.GetItems().then((result) => {
                    $scope.Items = ["I", "was", "loaded", "asynchronously"];
              });        
        };
        
        return {
            templateUrl: "/apps/components/MyComponent/MyComponent.html",
            controller: controller,                
        };
    });

As you can see component comprises of controller and other directive options that drives how your component will function. Components not required having controller but we will make that default for our design framework as a standard.

So let’s first create the class to define our component that will act as controller as well

    abstract class BaseComponent<T extends IScope> {
        static $inject = ["$scope", "ServiceLocator"];
        private serviceLocator: ServiceLocator;
        public Scope: T;
        

        constructor(scope: T, services: ServiceLocator) {
            this.Scope = scope;
            this.serviceLocator = services;
            this.Init.bind(this);
            this.Init();
        }

        abstract Init(): void;


        Services(): ServiceLocator {
            return this.serviceLocator;
        }

        Parent(): IScope {
            return this.Scope["$parent"] as IScope;
        }
    }

That’s great so we have class to act as controller but if you notice that’s not how components are being setup. Angular expects the function that returns definition of the component. We cannot use above approach to register it as component as we did for services and controllers.

If you really compare Directives and Components are very similar in the way its setup, the only difference is Components are light weight and simple form of Directive. But I will consider Directives only approach for our design to support previous versions of Angular and anyway our end result is going to be much simpler than original Components setup recommended.

Below are the definitions you can define for directives:

    interface IDirective {
        compile?: IDirectiveCompileFn;
        controller?: any;
        controllerAs?: string;
        link?: IDirectiveLinkFn | IDirectivePrePost;
        multiElement?: boolean;
        name?: string;
        priority?: number;
        require?: string | string[] | {[controller: string]: string};
        restrict?: string;
        scope?: boolean | Object;
        template?: string | Function;
        templateNamespace?: string;
        templateUrl?: string | Function;
        terminal?: boolean;
        transclude?: boolean | string | {[slot: string]: string};
    }

Let’s create interface and include these options there

    interface ICompoenent {
        compile?: ng.IDirectiveCompileFn;
        multiElement?: boolean;
        priority?: number;
        require?: string | string[] | { [controller: string]: string };
        scope?: boolean | Object;
        terminal?: boolean;
        transclude?: boolean | string | { [slot: string]: string };
        template?: string | Function;
    }

I did not include some of properties since those will be automated and some are I never really needed. You can add or extend it as you need.

Lets define the decorator to register the component with definition as required by Angular.

    function Component(name: string, options: ICompoenent) {
        return (target: Function) => {
            var directiveOptions = options as ng.IDirective;

            directiveOptions.controller = target;
            directiveOptions.scope = (directiveOptions.scope || {});
            directiveOptions.templateUrl =
                (directiveOptions.templateUrl || "/apps/components/" + name + "/" + name + ".html");

            if (target.prototype.Link)
                directiveOptions.link = target.prototype.Link;
            angular.module('portal').directive(name, function () { return directiveOptions; });
        };
    }

Here I’m using pre decided path for all component’s template url. I do not like to define html templates inside the code and always tends to have dedicated template in-place for Angular to look for. You can change that behavior, as you like though.

Lets put all these together and see how our final implementation for component looks like

    var option: ICompoenent = {
        transclude: true
    };

    @Component("MyComponent", option)
    class MyComponent extends BaseComponent<IMyComponentScope>{
        Init(): void {
            this.Scope.Items = ["I", "was", "loaded", "synchronously"];
            this.Services().Service1((service) => {
            return service.GetItems()
                    .then((result) => {
                          this.Scope.Items = ["I", "was", "loaded", "asynchronously"];
                    });
            });
        }
    }

That’s it. Now we got the same goodies of controller and services in component as well.

So far what we achieved?

  1. Decorators that will take care of registering your controller, service and components
  2. No dependency required to provide in constructor
  3. All dependencies are always available for developer though out the application though base implementations
  4. Developer don’t need to worry about loading services from server, our framework will take care of loading it if it’s not already loaded.

Project structure

Now that we have our basic framework design ready we need to structure our project properly.

There are common two structures that I usually follow:

  1. Default MVC.net style
        app
            \controller
                \module1
                    \module1controller.ts
            \views
                \module1
                    \module1view.html
            \services
                \module1
                    \module1service.ts
            \components
  2. Modular structure (Uncle Bob’s screaming architecture)
        app
            \module
                \controller
                    \modulecontroller.ts
                \views
                    \moduleview.html
                \moduleservice.ts
            \components


    In the final source code provided with this article, I have used second one Modular structure with few modifications as shown below.

  3. Final standard structure of our framework
        app
            \moduleName
                \controllers
                    \moduleName-action1.controller.ts
                    \moduleName-action2.controller.ts
                \views
                    \moduleName-action.html
    		\moduleName-action2.html
                \moduleName.service.ts
            \components
                \componentsName
    		\componentsName.ts
    		\componentsName.html
    		\componentsName.css
    


    As you can see, I’m grouping controllers and views for that controller in modules (features). Modules are basically just high level group of relevant features. I have choose to have single service file per module approach here, but sometime depending on application if more services are required in one module then I group them into services folder just like controllers and views in relevant module. That approach is not covered here in this article, but if you choose to then its very simple to achieve that. You just have to change default lookup path in out Load method of BaseService class.

    And components are kept separate since those are common part of application and they are just grouped by their name. This convention has worked great so far to me and never has to worry about violating any thumb rules for structuring the application irrespective of any framework I choose to use.

File naming convention

Finally, since our base classes and decorator is doing guess work to decide which view or service to load automatically, we will need to have definite file naming standards in application.

Controller file name:
I generally prefer to name controller with their action, something like:
modulename-action.controller.ts

As you can see, module name and action is separated by hypen, that gives easy understanding by looking at just file what this particular file is for.

View file name:
View names follow similar convention
modulename-action.html

Service file name:
I usually have only one service file per module, but you can extend that behavior as you prefer.
modulename.service.ts

Putting this all together in example our project is structure as:

    app
        \employee
            \controller
                \emlpoyee-view.controller.ts
            \views
                \emlpoyee-view.html
            \employee.service.ts
        \components


Let’s see how our final working example looks like:

    namespace Portal.Employee {
        export interface IEmployeeViewScope extends Core.IScope {
            GridOptions: uiGrid.IGridOptionsOf<Employee.EmployeeViewModel>;
        }

        @Core.Controllers.Controller("Portal.Employee.EmployeeViewController")
        export class EmployeeViewController extends Core.Controllers.BaseController<IEmployeeViewScope> {
            Init(): void {
                this.Scope.GridOptions = {};
                this.Scope.GridOptions.data = [];
                this.Scope.GridOptions.columnDefs = [
                    { field: 'name' },
                    { field: 'gender' },
                    { field: 'company', enableSorting: false }
                ];
                this.Scope.GridOptions.onRegisterApi = (gridApi) => {
                    this.LoadData();
                };
            }
            LoadData(): void {
                this.Services()
                    .EmployeeService((service) => {
                           return service.GetAll()
                                .then((result) => {
                                      this.Scope.GridOptions.data = result;
                            });
                    });
            }
        }
    }

    namespace Portal.Employee {
        export class EmployeeViewModel {
            name: string;
            gender: string;
            company: string;
        }
        @Core.Services.Service("Portal.Employee.EmployeeService")
        export class EmployeeService extends Core.Services.BaseService {
            GetAll(): Core.IPromise<Array<EmployeeViewModel>> {
               return this.Http()
                    .get("https://cdn.rawgit.com/angular-ui/ui-grid.info/gh-pages/data/100.json")
                    .then((result) => {
                        return result.data;
                    });
            }
        }
    }


Download the source code solution with final implementation from my CodeProject post here.

Some of the topics that I’ll be covering in next article are already part of the code. Go ahead and explore those features included like:

  1. Better routing implementation
  2. Define page title from Route registration itself (Not included in code)
  3. Lazy loading controller’s files as required (Not included in code)
  4. Angular 2 support. No code change required in implementation, another benefit of this approach, developer don’t have to worry if its Angular 1.5 or 2 working behind.

Please share and comment if you find it useful. Comment if you have any other issues that you want to explore with this approach or any suggestions.

Angles of Angularjs, part 1

Tags

, , ,

Recently angularjs has caught huge attention from frontend developers. There are many frameworks available to choose from and most of them are baked with very common features. EmberJS that started way before AngularJS and backed by Apple, ExtJS which is also a full featured MVC framework, and then the Backbone.js. What is driving most of us to AngularJS is the community that is very active for resolving issues and has huge interest from tech world to extend its capability. And now with its recent development in TypeScript, it’s teasing lot more developers to play with it.

There have been many changes in this library that diverted lot of us to think this library is not going in right direction and may disappear just like other frameworks. But as of now Angular is still evolving and keeping our interest in it.

From my past experience working with AngularJS and having .net background I found there is something that really missing or not standardized when compared with other MVC frameworks. It’s not that AngularJS does not provide those feature at all but problem is no one is focusing on those aspects as a framework rather just tries to use it as is because some top blogger says so. Well one size cannot fit all. Maybe the way I want to setup this framework, others would not even require.

This article is not to discuss on what this framework is or what the alternatives to angularjs are. Rather we are going to look deeper into some aspects of framework to overcome the boilerplate code to make use of AngularJS even sweeter.

@inject, @injectable, $inject, $injector… what?

Dependency injection has been the most interesting feature of AngularJS. It is the most valuable aspect of development for complicated applications with lots of interrelated modules and services.

Please read the Angular implementation from official site https://docs.angularjs.org/guide/di.


ref: https://docs.angularjs.org/guide/di

So this thing works great, what exactly the problem is here?

  1. You have to pass all the dependencies in parameters. Unquestionably not a best practice and not maintainable. Imagine you need more than 5 dependencies to inject everywhere. And let’s say you were almost at the half way through development and some design change needs some more dependencies.
  2. Other problem described in official guide is dependency parameter name changes in minifiaction process that makes Angular unable to find the correct dependencies. Angular provides workaround by allowing to provide $inject variable or inline parameters to specify those dependencies as array in string format (v1.5 and earlier), @injectable and @inject (v2+). That’s good. But that also adds more cons to my first point I mentioned above since now you have to take care of additional strings, its casing in conjunction to adding parameter in constructor and most importantly its order.
  3. Angular doesn’t really know whether dependencies you need are loaded or not. And doesn’t provide any way to load it from server if it’s not loaded. That means you either always have to load all the dependencies before your constructer invokes, including interrelated dependencies. Which quite not practical in real world complex application development.

Let’s try to see how we can get over these issues.

One quick solution that I think of is Service Locator pattern. In fact Angular provides the service locator using $injector. Great that solves our second problem. If we just inject that object as parameter and our code will look nice.


ref: https://docs.angularjs.org/api/auto/service/$injector

But if developers add this code everywhere they requires, then it will be even worse than the actual problem we are trying to fix. I’ll rather have common service or factory that provides dependency instances whenever I need.


Great we worked around our first 2 issues and now developers have to inject only service locator, that’s a big improvement.

We can still improve this further by using inheritance. So basically we will abstract these common injection part to parent classes and developers will just have to implement those parent and done. That’s a huge improvement when we compare our original implementation with this approach.


Similarly, we will implement the BaseController to use this ServiceLocator


There are two additional things to notice:

First, I have made BaseController generic to implement IScope type. It’s just to define scope object for every controller inheriting from this base class.

And second is Init abstract method. Since we have to predefine the constructor we don’t want developer to define that again in child controllers but we still need to have a method that get invoked while creating the instance.

Right I’m not worrying about controllerAs part since my implementation is just for illustration purpose.

Finally, our controller will look like this.


That’s it, isn’t it clean and maintainable? Developer will focus less on taking care of Angular and more on the functionality.

We can implement the Components in similar fashion. It needs some extra things to take care to work with AngularJS. That I’ll cover in next article.

Another issue that I mentioned at the beginning is dynamically loading the services, we didn’t really solve that yet. I’ll be showing that as well in my next article with complete source code.

Hope it gives some idea and motivates developers to use AngularJS as a framework than just a library.

Simple Sort for IEnumerables

Tags

, , , , , , , , ,

Just a quick upload to explain the Sort method for IEnumerable objects that might help in many cases and which is very easy to implement. In this approach I have used Extension method , Linq operator and little bit of reflection. You can also do same by calling Array.Sort, or by List’s Sort method using IComparable implementation but as I say its just an alternative that I found very handy than the existing one.

Lets say we have a class Employee and an array of Employee class

    public class Employee
    {
        public string Name { get; set; }
    }

    var employees = new Employee[]
                    {
                        new Employee(){Name = "Navnath1"},
                        new Employee(){Name = "Navnath2"},
                        new Employee(){Name = "Navnath3"},
                        new Employee(){Name = "Navnath4"},
                        new Employee(){Name = "Navnath5"}
                    };

Thankfully .Net has Linq which does our job instantly, by using OrderBy  and OrderByDescending operaters. like

    employees.OrderBy(employee => employee.Name);

Iterating over this result will give our required result.

Lets make it more usable and simple. For this we will create extension method with Sort method that takes sort by name and direction of sorting.

    public static class IEnumerableExtension
    {       
        public static IEnumerable<TElement> Sort<TElement>(this  IEnumerable<TElement> source, string sortBy, SortDirection sortDirection = SortDirection.Ascending)
        {
            if (source != null)
            {
                PropertyInfo fieldInfo = typeof(TElement).GetProperty(sortBy);

                if (fieldInfo != null)
                {
                    source = sortDirection == SortDirection.Ascending ?
                        source.OrderBy(emp => fieldInfo.GetValue(emp, null)) :
                        source.OrderByDescending(emp => fieldInfo.GetValue(emp, null));
                }
            }

            return source;
        }

        public static IEnumerable<TElement> Sort<TElement, TKey>(this IEnumerable<TElement> source, Func<TElement, TKey> sortByExpression, SortDirection sortDirection = SortDirection.Ascending)
        {
            if (source != null)
            {
                source = sortDirection == SortDirection.Ascending ?
                    source.OrderBy(sortByExpression) :
                    source.OrderByDescending(sortByExpression);
            }

            return source;
        }
    }

Thats it… Now you can simply call Sort on any object that implements IEnumerable  interface,

    employees.Sort("Name", SortDirection.Descending); //Using string  OR
    employees.Sort(emp => emp.Name, SortDirection.Ascending); //Using Expression  OR
    employees.Sort(emp => emp.Name); //Ascending is default

This approach can help specifically in ASP.Net where DataGrid, GridView needs custom sorting implementation using field name in string type and direction to sort on binding object.

Nothing much special but just a handy method to help sorting… 🙂

Widget based portals (WebParts) with personalization for ASP.Net Webforms and MVC – Part 2

Tags

, , , , , , , , , ,

Content
Part 1: Defining and analyzing basic view structure and components
Part 2: Designing Client side object module

Introduction

In the last post we looked at our basic implementation of view for CatalogZone, LayoutZone, and WebPartZone. These three zones will be our core components that collectively form the WebPartManager which is a non-visual component of our WebPart implementation.

Today in this post I have decided to first start with client side implementation so that we could get the brief idea of components functionalities. To start with this let’s see what we can possibly have to have this to work.

Client side code mock:

 var CatalogZone1 = WebParts.CatalogZone('CatalaogZone1');
 WebParts.WebPartManager.CurrentWebPartManager.CatalogZones.add(CatalogZone1);

 var WebPartZone1 = WebParts.WebPartZone('WebPartZone1');
 var WebPartZone2 = WebParts.WebPartZone('WebPartZone2');
 var WebPartZone3 = WebParts.WebPartZone('WebPartZone3');
 var WebPartZone4 = WebParts.WebPartZone('WebPartZone4');
 WebParts.WebPartManager.CurrentWebPartManager.WebPartZones.add(WebPartZone1);
 WebParts.WebPartManager.CurrentWebPartManager.WebPartZones.add(WebPartZone2);
 WebParts.WebPartManager.CurrentWebPartManager.WebPartZones.add(WebPartZone3);
 WebParts.WebPartManager.CurrentWebPartManager.WebPartZones.add(WebPartZone4);

 CatalogZone1.WebPartDefinitions.add('title', 'discription', 'url');
 CatalogZone1.WebPartDefinitions.add({ title: 'title', discription: 'discription', url: 'url' });

 var WebPartDefinitions1 = new WebParts.WebPartDefinition('title', 'discription', 'url');
 CatalogZone1.WebPartDefinitions.add(WebPartDefinitions1);

 var StaticWebPartZone1 = WebParts.WebPartZone('StaticWebPartZone1');
 StaticWebPartZone1.CanAcceptWebParts = false;
 StaticWebPartZone1.LoadWebPart('id', { title: 'title', discription: 'discription', url: 'url' });

OK this looks prettier up till now and I think with this much implementation we are good to go ahead. Currently I’ve not considered the LayoutZone and templatization so that we get our basic required look first.
So lets design the classes required to get this working.
Here we are going to need collection class to implement the list of objects as in Javascript array provides very minimal functionality we are going to make out own CollectionBase class like one we use in .Net

    var CollectionBase = function () {
        var list = [];

        list.add = function (object) {
           list.push(object);
        }

        list.remove = function (object) {
            var index = this.indexOf(object);

            if (index >= 0) {
                delete list[index];
                list.splice(index, 1);
            }
        }

        list.indexOf = function (object) {
            for (var index = 0; index <= list.length - 1; index++) {
                if (list[index] == object)
                    return index;
            }

            return -1;
        }

        return list;
    }

Lets add WebPartManager, CatalogZone, WebPartZone, WebPartTemplate, WebPartDefinition, WebPart to WebParts namespace. I have created a NamespaceHelper class which takes care of creating classes

    var NamespaceHelper = {
        get: function (namespace) {
            if (namespace && typeof namespace == 'string') {
                var namespaces = namespace.split('.');

                var result = null;
                for (name in namespaces) {
                    var currentClassName = namespaces[name];
                    result = (result || window)[currentClassName];

                    if (!result)
                        break;
                }

                return result;
            }
        },

        create: function (namespace) {
            if (namespace && typeof namespace == 'string') {
                var namespaces = namespace.split('.');

                var currentNamespace = window;

                for (name in namespaces) {
                    var currentClassName = namespaces[name];

                    if (!currentNamespace[currentClassName]) {
                        currentNamespace[currentClassName] = {
                            "namespace": (currentNamespace.namespace ? currentNamespace.namespace + '.' + currentClassName : currentClassName),
                            "class": currentClassName
                        }
                    }

                    currentNamespace = currentNamespace[currentClassName];
                }

                return currentNamespace;
            }

            return null;
        }
    }

    var WebParts = NamespaceHelper.create('Navnath.Web.UI.WebControls.WebParts');

    WebParts.WebPartManager = function () {
        var webPartManager = {
            ImportWebPartsURL: null,
            WebPartZones: new CollectionBase(),
            CatalogZones: new CollectionBase(),

            BeginImportWebParts: function (catalogZone, callback) {

            }
        };

        return webPartManager;
    };

    WebParts.CatalogZone = function () {
        return {
            CanAcceptWebParts: true,
            ImportWebPartsURL: null,
            WebPartDefinitions: new CollectionBase(),

            BeginImportWebParts: function (callback) {

            },

            LoadWebPart: function (webPartsDefinition) {

            }
        };
    };

    WebParts.WebPartZone = function () {
        return {
            WebParts: new CollectionBase(),
            LoadWebPart: function (webPartsDefinition) {

            }
        };
    };

    WebParts.WebPartTemplate = function () {
        return {
            Metadata: null,
            DataSource: null,
            DataBind: function () {

            },

            View: function () {

            }
        };
    };

    WebParts.WebPartDefinition = function () {
        return {
            CanDrag: true,
            ID: null,
            Template: null,
            Title: null,
            URL: null,

            Clone: function () {

            }
        };
    };

    WebParts.WebPart = function () {
        return {
            Definition: null,
            ID: null,
            Visible: null,
            Zone: null,

            Load: function () {

            },

            Render: function () {

            }
        };
    };

    WebParts.init = function () {
        var WebPartManager1 = new this.WebPartManager();
        this.WebPartManager.CurrentWebPartManager = WebPartManager1;
    };

    WebParts.init();

Object Module:

As we have our basic classes in place we can now start adding the functionalities in them. In next post to speed up things I’ll implement the complete client side module to get WebPartDefinition, WebPart in work. Leter we will add drag and drop functionality to it as we move ahead.

That’s it for now. Please post your suggestions as it will help me to consider it in next post.

Widget based portals (WebParts) with personalization for ASP.Net Webforms and MVC – Part 1

Tags

, , , , , , , , , ,

Content
Part 1: Defining and analyzing basic view structure and components
Part 2: Designing Client side object module

Introduction
This is my first post in this series of creating a widgets based web portal (Dashboard) particularly for .Net MVC using power of JQuery. At the end of this series, my efforts will be toward making a reusable component that should leverage an optimal solution for integrating different types of contents into widgets. In particular interest to this series will be utilizing existing behavior of ASP.Net WebPart as following:

  1. Page Layout customization
  2. WebPart drag drop
  3. Edit WebPart
  4. Customize WebPart
  5. WebPart Personalization
  6. WebPart connection
  7. Remove, Minimize, Refresh WebPart

Let’s first start with the rough design of portal. For this we will look into existing implementation and my favorite one BBC.com dashboard. Like in ASP.net WebParts, one WebPartManager is mandatory in page which will provide common accessibility for other components at server and client side. WebPartCatalogZone will act as storage of WebPart description like its title, URL, image, etc… These descriptions can be added or removed from server and client side which in turn will get reflected in catalog zone or customization pane. We could enhance this widget by providing customized templates which can be customized at design time to introduce verity of looks for same content types. For now we will support simple template like lists, image cover flow, grids. And will keep on adding as required.  Once the use selects this widget from pane will gets added into relevant WebPartZone using templates. For templates currently I’m considering Microsoft Ajax Dynamic templates. This article shows excellent implementation of dynamic templates for portal.

This dashboard will be composed of following components/elements (we will add it as we proceeds with implementation):

  1. WebPartManager
  2. WebPartCatalogZone
  3. WebPartTemplate
  4. WebPartZone
  5. WebPart (Widget Description)
  6. Client Side Object Module for above components

Class Diagram:

Page Layout:
So let’s decide how our server side implementation should look like. We are currently not going to look into styling but will start with basic HTML elements first. Then we will convert them into components and add required functionalities.

CSS:

 #CotalogZoneContainer
 {
 width: 990px;
 margin-left: auto;
 margin-right: auto;
 background-color: #ababab;
 padding: 5px;
 }

 #CotalogZoneContainer .add
 {
 text-align: right;
 }

 #CotalogZoneContainer .template
 {
 background-color: gray;
 overflow: auto;
 height: 100px;
 }

 #CotalogZoneContainer .layouts
 {
 width: 250px;
 float: left;
 overflow: auto;
 margin-top: auto;
 margin-bottom: auto;
 height: 100px;
 }

 #CotalogZoneContainer .webparts
 {
 width: 730px;
 float: left;
 margin-top: auto;
 margin-bottom: auto;
 overflow: auto;
 height: 100px;
 }

 #WebPartZonesContainer
 {
 width: 990px;
 margin-left: auto;
 margin-right: auto;
 padding: 0px;
 }

 #WebPartZonesContainer #StaticWebPartZone1
 {
 width: 48%;
 height: 500px;
 }

 #WebPartZonesContainer #WebPartZone1
 {
 width: 50%;
 height: 500px;
 }

 #WebPartZonesContainer #WebPartZone2, #WebPartZonesContainer #WebPartZone3, #WebPartZonesContainer #WebPartZone4
 {
 width: 320px;
 }

 #WebPartZonesContainer .WebPartZone
 {
 margin: 2px;
 border: 1px solid #ababab;
 float: left;
 }

HTML:

<div>
<div id="CotalogZoneContainer">
<div class="add">
                Customize Page</div>
<div class="template">
<div id="LayoutZone1" class="layouts">
                    layouts</div>
<div id="CatalaogZone1" class="webparts">
                    catalog</div>
</div>
</div>
<div id="WebPartZonesContainer">
<div id="StaticWebPartZone1" class="WebPartZone">
                zone</div>
<div id="WebPartZone1" class="WebPartZone">
                zone</div>
<div id="WebPartZone2" class="WebPartZone">
                zone</div>
<div id="WebPartZone3" class="WebPartZone">
                zone</div>
<div id="WebPartZone4" class="WebPartZone">
                zone</div>
</div>
</div>

OK, so this will look like something

That’s it for now. I’ll try to add new post every week. Till then please add any suggestions and questions.

URL Rewriting

URL Rewriting

Introduction
URL rewriting is a process of redirecting the requested resource to the other resource without changing requested URL. It means the result of requested URL will be furnished from the location whose URL might be different than the requested one.

Generally all the requested URLs are mapped with physical file (ex .aspx file) which contains the requested resource.

There are many scenarios where we might need to implement this concept.

1. When user tries to access this page, virtual path mapped with this physical location get furnished if available. This result in broken link if requested page/resource is not found at specified location. This usually happens when pages get moved doe to site restructuring. Using Rewrite we can simply redirect the request to actual moved location.

2. Most of the times developer stores required information as URL parameters, this makes URLs harder to remember and error some to type. Also key, value pairs used for URL query string makes no sense for end user to type as he/she might not be aware of its use.

Example:

Consider a page displaying employee data having URL http://site.com/empdetail.aspx?id=1. Using Rewriting we effectively make this URL more meaningful as http://site.com/employees/username. This adds more usability for end user as he/she can just type http://site.com/employees to list all the employees or can use http://site.com/employees/a-b to list all employees name starting with a to b only.

This concept can also be used creatively for culture based page rendering. Like MSDN pages every page can be followed by the culture name like http://site.com/en-us/employees/username. This makes the URL more hackable to use different culture for same page.

3. Creating robust site structured URL routing engine. Web application can maintain the desired URLs with key notations and actual URL to redirect to.

URL Request handling
Following steps elaborates the basic request (URL) handling.

1. Accepting request

Every request made to server first gets captured by IIS. IIS 6 uses kernel mode device driver called HTTP Protocol Stack (namely HTTP.sys) to listen HTTP request. Earlier versions of IIS use windows sockets (Winsock) for same purpose.

2. Request Handling

Once IIS receives the request it gets processed though ISAPI (Internet Service Application Programming Interface) extensions and ISAPI filters. ISAPI extensions create the desired response to send to end user, whereas ISAPI filter handles all the events to control the processing of request.

ISAPI extensions are mapped to particular file extensions that it need to handle in IIS. Depending on the file extension the appropriate ISAPI extension gets loaded. For example to handle classic asp file IIS uses asp.dll and for ASP.Net page requests it uses aspnet_ISAPI.dll. Along with this ISPAI filter also gets loaded which is responsible for Authentication, Authorization, Logging, Monitoring and URL rewrite. ISAPI filter invokes the events to control this request and can manipulate it at any time needed.

ISAPI extension and ISAPI filter are unmanaged code and need to be implemented at IIS side. However .Net Framework provides the exact functionality for web application using ASP.Net Engine. Once request is recognized IIS sends it to ASP.Net Engine through aspnet_ISAPI.dll

3. ASP.Net Engine

ASP.Net Engine offers the similar functionality as ISAPI filter and ISAPI extension through HTTP Module and HTTP Handler. HTTP Module manages all the events for lifecycle of the request and HTTP handler retrieves the response to load from the specified location.

Source: MSDN

ASP.Net Engine allows intercepting request to other location / URL at both HTTP Module and HTTP Handler as described below in Implementation section.

Implementation

Implementation of URL Rewrite is very easy and can be done using System.Web.HttpContext class. HttpContext (Namespace: System.Web [more info: http://msdn.microsoft.com/en-us/library/system.web.httpcontext.aspx]) is a class which gets created per request to encapsulate all the HTTP specific information like Request, Response, Server Information, Cache and commonly used Current static property that retrieves current HTTP request object.
HttpContext class provides a method RewritePath. This method allows requested URL to differ from the requested one. This call intercepts path in cookie-less state.

URL rewriting can be implemented using following ways:
1. Using HTTP Module
2. Using HTTP Handler

1. HTTP Module

ASP.Net provides built-in HTTP Modules that control the request during its lifecycle. Custom HTTP Module can be implemented in ASP.Net application to manage this lifecycle. ASP.NETprovides IHttpModule to create custom Http Modules which need to be registered in configuration file of the application being using it.

HTTP Module plays important role in authentication and authorization of request so it’s important to decide at which point URL Rewrite can be implemented. In the lifecycle of request BeginRequest is the very first event gets fire before authorization and authentication. It’s always recommended to rewrite the path in BeginRequest or AuthenticateRequest so that to ensure the integrity of the authentication and authorization.

Followings are the in-built modules used by ASP.Net engine for authentication and authorization of request.

I. FormsAuthenticationModule:

Determines if user is authenticated using AuthenticateRequest event handler.
II. FileAuthorizationMoudle:

Determines if user account in which current application is running has adequate authorization when using Windows Authentication using AuthorizeRequest event handler.

III. UrlAuthorizationModule:

This module is configuration through web.config’s location section and checks if requested URL can be accessed for requester using AuthorizeRequest event handler.
Execution of these events is as follows:

Security perspective there are three approaches that needs to be considered while deciding event when rewrite the path.

  • No Authentication: In this case you can rewrite path in any of BeginRequest, AuthenticateRequest or AuthorizeRequest event of application.
  • Form Authentication: In this case path should be rewritten in AuthorizeRequest event handler so that UrlAuthorizationModule module should only refer to original requested URL rather than rewritten URL.
  • Windows Authentication: In this case path should be rewritten in BeginRequest or AuthenticateRequest.

Sample 1: URL Rewriting using HTTP Module
publicclassURLRewriter : IHttpModule
{
#regionIHttpModule Members

publicvoid Dispose()
{

}

publicvoid Init(HttpApplication context)
{
context.BeginRequest += newEventHandler(context_BeginRequest);
}

void context_BeginRequest(object sender, EventArgs e)
{
HttpApplication application = sender as HttpApplication;

if (application != null)
{
if (application.Context.Request.Url.AbsolutePath.ToLower().Contains("/employee/"))
{
string employeeName = application.Context.Request.Url.Segments[application.Context.Request.Url.Segments.Length-1].Replace(".aspx","");

 

application.Context.RewritePath("~/EmployeeDatails.aspx?name=" + employeeName);
}
}
}

#endregion
}

In above example we are using BeginRequest event handler where we are checking outexpected URL and then rewriting it to the actual path if matches.
This custom Http Modules can be registered in configuration file of application as shown below

Registering custom Http Module in web.config of application
<httpModules>
<addname="URLWriter"type="HttpMdl.URLRewriter"/>

</httpModules>

2. HTTP Handler

ASP.Net offers URL rewriting using Http Handler or Http Handler Factory. As discussed Http Handler returns the response of the content to render at end user. Whereas Http Handler Factory returns the appropriate handler depending on the type of file being requested.

Custom Http handler factory can be imeplemated using IHttpHandlerFactorywhich needs to override the method GetHandler() that returns the instance of the handler of type IHttpHandler. As long as file type remains same we don’t need to implement custom HttpHandler. ASP.Net provides the default PageParserPage parser for .aspx files which includes the method GetCompiledPageInstancethat returns the compiled page from given virtual path.

Following code snippet illustrates the implementation of Http handler factory for URL rewriting.

URL Rewriting using HTTP Handler Factory
publicclassURLRewriter : IHttpHandlerFactory
{

publicIHttpHandler GetHandler(HttpContext context, string requestType, string url, string pathTranslated)
{
if (context.Request.Url.AbsolutePath.ToLower().Contains("/employee/"))
{
string employeeName = context.Request.Url.Segments[context.Request.Url.Segments.Length - 1].Replace(".aspx", "");

context.RewritePath("~/EmployeeDatails.aspx",string.Empty, "name=" + employeeName );

returnPageParser.GetCompiledPageInstance("~/EmployeeDatails.aspx", context.Server.MapPath("~/EmployeeDatails.aspx"), context);
}

returnPageParser.GetCompiledPageInstance(url, pathTranslated, context);
}

 

publicvoid ReleaseHandler(IHttpHandler handler)
{

}
}

In above example we are return default Http Handler after rewriting Url path to actual location.
This custom Http handler Factory can be registered in configuration file of application as shown below

Registering custom Http handler factory in web.config of application
<httpHandlers>
<addverb="*"path="*.aspx"validate="false"type="HttpHdl.URLRewriter"/>
</httpHandlers>

References
1. http://msdn.microsoft.com/en-us/library/ms972974.aspx
2. http://download.microsoft.com/download/0/4/6/0463611e-a3f9-490d-a08c-877a83b797cf/MSDNURLRewriting.msi
3. http://www.theserverside.net/tt/articles/showarticle.tss?id=IIS_ASP