Wednesday, January 16, 2013

Introduction to MVC in ASP.NET

MVC - Model - View - Controller
Most of the ASP.NET applications consist of UI + Code behind + middler layer + data layer.

Actually code behind(.aspx.cs) is not independent from .aspx file. We can not compile anyone one of them independently.

Because of that there are few problems we face while -
a) Testing - unit testing becomes tricky.
b) Code re usability - as .aspx.cs and .aspx files are connected with each other, its not straight to put that code somewhere else and reuse it in other classes.

MVC - write all your code behind in controller class and let UI be independent. return view object to UI and  show it to the user.

Session Management in MVC -
The problem with using the ASP.NET session or view state object is the scope. ASP.NET session objects have session scope and view state has page scope. For MVC we would like to see the scope limited to the controller and the view. In other words we would like to maintain data when the hit comes to the controller and reaches the view and after that the scope of the data should expire.
That’s where the new session management technique has been introduced in the ASP.NET MVC framework, i.e., ViewData. It is mainly to pass data fro controller to view.

Developer's notes

The view does not have a code-behind. So to display the view we need to use the <%: tag in the ASPX page.

Once we create MVC project and create controller, it will be given name as abccontroller and then will have to create view for this controller. If we want to invoke that view then will have to hit the url like this -
http://localhost/abc....note that its abc, not abccntroller .

Is it possible to have 2 view with one controller ?? - yes
or 2 controller for one view?? No;
Because if you see the url, there we actually hit the controller name and accordingly the view is decided and in controller we actually return new View object, this object is handed over to view which finally renders the page depending upon the object passed. Its not possible to pass view object to another controller and then send the final consolidated view.We will need to modify the design a little bit and will have to hack it, if we want anything like this.

Importance of Httppost attribute -
In controller above View definition, we can  write [Httppost]. It means that this view will handle only post requests. If we put this attribute and then send a GET request then we will get 404 response.

MVC Routing -
we can have multiple URL’s mapped to one controller or you can have more than one controller mapped to a single URL.
It would be great if we have some kind of mechanism by which we can configure these mappings. That’s what exactly MVC routing is meant for. Check the Global.asax file, all the mappings are stored there.
All routing mapping are stored in to a collection called as ‘routes’. This collection belongs to the namespace “System.Web.Routing”. To add a route you need to call the ‘MapRoute’ method and pass three parameters “name”,”url” and “defaults”.

If you check Global.asax you will find following entry there -
routes.MapRoute(
 "Default", // Route name
 "{controller}/{action}/{id}", // URL with parameters
 new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);

This is the default route create by visual studio project. It means that if you hit following url:
http://localhost:2406/customer/DisplayAnotherCustomer ; Then it will invoke "customer" controller with "DisplayAnotherCustomer" as action. If you notice there is an id parameter also which is optional.
Lets try to modify the url and try to make it like this - http://localhost:2406/mvctest/customer/DisplayAnotherCustomer.

To do so i ll comment the mentioned line from Global.asax and will put the following line instead-
routes.MapRoute(
 "Customer", // Route name
 "mymvc/{controller}/{action}/{id}", // URL with parameters
 new { controller = "Customer", action = "DisplayAnotherCustomer", id = UrlParameter.Optional } // Parameter defaults
);

I have given route a name as "Customer" and mentioned the url to be "mymvc/{controller}/{action}/{id}".

Validation by route-
If we want to put any constraint(or validation), then we can use 4th parameter in MapRoute constructor. For example if we want the url like this - http://localhost:2406/mvctest/customer/DisplayAnotherCustomer/1
And depending upon number passed we want to take some action. Now its possible to put constraint in the url in following way -

routes.MapRoute(
 "Customer", // Route name
 "mymvc/{controller}/{action}/{id}", // URL with parameters
 new { controller = "Customer", action = "DisplayAnotherCustomer", id = 0 } // Parameter defaults
 , new { id = @"\d{1,2}" }
);
4th parameter take regular expression, where we have allowed all 2 digit numbers. Hence passing any string or any other character won't work(it will simply give 404).

Navigation -
If we want to provide navigation from one page to another, we can't directly provide href link on one page, as it is violation of MVC rule. Directly providing href link to the page will take us to the view first, rather than controller. As per MVC principle the hit should come to the controller first.
So the idea is to use Action instead of directly using aspx page.
Here is example -

<a href="GotoHome">Go Home</a><br />
GotoHome is action, which will load required view for us.

Wednesday, January 9, 2013

JavaScript Tips and Tricks-9

Lets try to understand the output of following function - 

function fun(){}
var fun1 = new fun();
var fun2 = fun(); //undefined
var fun3 = fun;

fun1.newProp1 = '1';
fun3.newProp2 = '2';

alert(fun1.newProp1);//-- 1
alert(fun3.newProp2);//-- 2

var fun4 = new fun();
alert(fun4.newProp2);//undefined

if we define fun in the following way -
function fun(){ return this;}
then fun2 will not be undefined, it will be window. because fun2 = fun() actually executes the function and assign the value back to fun2.
fun3 is also just pointing at the definition of fun, but we can not write var a = new fun3(); it will be undefined.

Moreover on the heap you will see just 2 objects, fun1 and fun4(along with the original definition of course).
Lets try to find the answer for following exercise -
    function fun(){
        this.a = '1';
        b = '2';
        var c = '3';
        return this;
    }
   
    var fun1 = new fun();
    alert('fun1.a ' + fun1.a);
    alert('fun1.b ' + fun1.b);
    alert('fun1.c ' + fun1.c);

    var fun2 = fun();
    alert('fun2.a ' + fun2.a);
    alert('fun2.b ' + fun2.b);
    alert('fun2.c ' + fun2.c);

    alert('window.a ' + window.a);
    alert('window.b ' + window.b);
    alert('window.c ' + window.c);

Answer -

var fun1 = new fun();
alert('fun1.a ' + fun1.a); //1
alert('fun1.b ' + fun1.b); // undefined
alert('fun1.c ' + fun1.c); // undefined

var fun2 = fun();
alert('fun2.a ' + fun2.a); //1
alert('fun2.b ' + fun2.b); //2
alert('fun2.c ' + fun2.c); // undefined

alert('window.a ' + window.a); //1
alert('window.b ' + window.b); //2
alert('window.c ' + window.c); // undefined