ASP.Net MVC 3 - An Overview Part 3
In ASP.Net MVC Part2 we have digged deep inside Controller.For eg: We have seen triple actions related to controller. ie; Action Method, Action Result, Action Filter. In this section we will dig a bit deeper inside ASP.Net MVC 3 View. As you know we are not using viewstate or session in ASP.Net MVC for state management. We will see here how to handle state in MVC,Razor View Engine,Layout Template,Html Helpers,Partial Views etc.
View in depth
View as it name implies gives user interface to the end user.In ASP.Net MVC, it is the view engine which is responsible for generating the view. Views does not contain any business logic or data validation logic.They are similar to ASP.Net web forms but like web forms views cannot be directly accessed via web browser.As I told you earlier, views are always rendered by a controller.
When ever a request comes to the MVC application,the controller handles the incoming request and depends upon the application logic it will communicate with the model to retrieve or update the data. The model in turn communicate with the database and updates the controller and the controller will render the
appropriate view. The view renders the appropriate UI by the help of data that is passed to it from the controller.There are different mechanisms for passing data from controller to view and vice versa. The controller action method passes the data to the view using the View method.
public class TestController : Controller
{
public ActionResult Welcome()
{
ViewBag.Message = "Welcome to world of ASP.NET MVC 3";
return View();
}
Here,the View method will call the view engine, which uses the data in the viewBag/ViewData to render to the view and to display it in the browser. Here parameter which is passed to the view is the ViewBag which is a property of the view and controller. ViewBag is a new feature introduced in MVC 3.
We can pass any data between view and controller ranging from a simple data type to a collections of a complex object.There are different methods for passing data from view to view,controller to view or vice versa.
Important among them are :
1. Viewdata : It is derived from ViewDataDictionary object. so it is a dictionay object and hence we can access its data by using key/value pair. It is fast and easy to implement. But It has a drawback. Since by default, in view data everything is stored as an object, we need to explicitly cast its contents to appropriate type.
a) Setting value in ViewData in Controller Action method :
public ActionResult Index()
{
ViewData["Test"] = "Test View Data";
return View();
}
b) Retrieving value from Viewdata in the View :
@ViewData["Test"] // @ is the razor syntax
2. ViewBag: This feature is not available in prior versions of MVC 3. It is a wrapper built above ViewData, and it is dynamic in nature.They are
stored as key/value pair in the viewdata dictionary.Since its dynamic no explicit casting is required. Also we can dynamically set/get values in viewbag without the use of strongly-typed classes.
a) Setting value in ViewBag in Controller Action method :
public ActionResult Index()
{
ViewBag.Test = "Test the View Bag";
return View();
}
b) Retrieving value from ViewBag in the View :
@ViewBag.Test // @ is the razor syntax
3. TempData : Like Viewdata,it is also a dictionary type property.It is used to store data at the time of redirection.Its like ASP.Net Session object but of short life span. While redirecting from one controller to another, both ViewBag and ViewData properties cannot be used. Here we can use Tempdata since it works for subsequent requests.
public class ProductController : Controller
{
[HttpPost]
public ActionResult Save(FormCollection formValues)
{
ProductModel productModel = new ProductModel();
TempData["UpdatePoduct"] = productModel; // set value in Tempdata
return RedirectToAction("SaveSuccess");
}
[HttpGet]
public ActionResult SaveSuccess()
{
ProductModel productModel = TempData["UpdatePoduct"] as productModel; // retrieve data from TempData.
return View(productModel);
}
}
4.ViewModel : We can use the ViewData, ViewBag, and TempData objects for the purposes of transporting small amounts of data from and to specific locations (ie; controller to view or between views). If we want to work with larger amounts of data like reporting data, dashboards, or work with multiple disparate sources of data, we will go for ViewModel object.
We can say view model is simply a class that hold all data that is needed by a view. Usually they are specific to each view and are not often reused
between views.
public class TestViewModel
{
public string Test { get; set; }
}
public Action Test()
{
var Testmodel = new TestViewModel { Test = "bar" };
return View(Testmodel);
} View Specifications
As a convention we should keep in mind the following points while creating a view.
1. Once we create a new project in ASP.Net MVC, it contains a Views folder.
2. Views folder contains folder per each controller and has same name as
controller.
3. Each view folder contains a view for each action method with in the controller with name same as action method. Strongly Typed Views
A strongly typed view bind form data to a particular class or view. A strongly typed view inherits from System.Web.Mvc.ViewPage<T> where T refers to the model class.Since we are specifying the type here we can access the intelliSense for the model class.Here is the advantages of using a strongly typed view.
1. Clean Syntax.
2. Strong Typing.
3. Compile Time Checking of property and method names.
4. Take advantage of Visual Studio intellisense. What is Razor View Engine ?
It is one of the new feature introduced in ASP.Net MVC3. It is the default view engine in ASP.Net MVC 3. In C# razor view's extension is .cshtml and in vb it is .vbhtml. It has following advantages while comparing to its prior view engine(.ASPX) counterpart.
1. Developer friendly since it is based on existing languages such as C# or VB.
2. Syntax is clean and concise compared to its prior view engine counterpart.
3. It has intellisence support.
4. Test Driven Development approach can easily followed by the help of razor view.
Following is the razor syntax.
@{
var items = new string[] {"mango","apple","orange"};
}
<body>
foreach(var item in items)
{
<li> @item </li>
}
</body>
In .ASPX view engine we used xml like tag with percentage sign to indicate the start and stop of code sequence as follows.
<% foreach(var item in items)
{%>
<% item %>
<% } %>
But In case of razor view, it uses @ character.Unlike its ancestor, Razor does not require you to explicitly close the code-block. Also Razor is smart enough to understand the general pattern of email.
ie; In the following example,it won't treat @ as a code delimiter.
some.body@anywhere.com
In the above example, if you don't want to consider @ chracter,then you can say @@ in the place of @.
some.body@@anywhere.com will display as some.bodyanywhere.com. What is code Expression ?
In razor view, we can write any C# or Vb code statement that we want with in @()syntax. The transition from C#/Vb to mark up and vice versa is possible through @ character. There are 2 basic types of transitions. It can be implicit code expressions or explicit code expression. Code expressions are evaluated and written to the response.
Example of Implicit Code Expression:
The item is @item
Example of Explicit Code Expression:
@(item.hours/8) //expression are placed in brackets What is Code Block ?
Code block also starts with @ and it contains one or more statements and will be enclosed in curly braces.
@{
ViewBag.Title = "Code Block Example";
}
What is Layout ?
Layouts are used to maintain consistent look and feel across multiple views. They behave like master pages in ASP.Net Web form but it provides more flexibility and simpler syntax than master pages.
Layout template can contain placeholders where views can place their content.The content placeholders can be defined using 2 methods.
1. @RenderBody() :It is located in the Layout page.It is same as ContentPlaceHolder in a Master Page but remember a layout page can contain maximum only one RenderBody.
2. @RenderSection() It is used to place fragments of markup in a layout page. Unlike RenderBody we can have as many RenderSection are possible in a layout page.
3. @RenderPage() : It will help to reuse markup and code that doesn't change across the site. Ex:Header and Footer.
A view must specify content for each section defined in the template, otherwise an exception will be thrown.
The following is an excerpt from the body tag of a sample Laypout template which is located as /Shared/_SampleLayout.cshtml.
<html>
<head>
<title>Layout Example </title>
</head>
<body>
@RenderSection("SiteMap")
//@RenderPage("Shared/_Header.cshtml") It will read from file you provided.
@RenderBody()
@RenderPage("Shared/_Footer.cshtml")
</body>
</html>
Here is my WebPage1 contents. We need to refer the above Layout page in WebPage1 on top as follows.
@{
Layout = "/Shared/_SampleLayout.cshtml";
}
@section SiteMap {
.
. // Your mark up goes here
.
}
<span> WebPage 1 specific content goes here <span>
Here mark up in the shared file _Footer.cshtml will be replaced in the footer.
Also note that, you can use RenderSection and RenderPage interchangeably.But there a slight difference how they works. From the above example you can see that, RenderPage will always reads the content from a physical file, whereas RenderSection runs code blocks that we provides in the content pages. Html Helpers
As I mentioned in earlier sections, ASP.Net doesn't have any server controls so we need to create the controls using Html tags. For an experienced developer it may be easy. But for others it may not be an easy task. Here comes the importance of Html Helpers.
Html Helpers are methods that returns a string where the string can represent any type of content. They help to render HTML content and thus reduce the tedious task of typing Html tags.
We can even write without any Html helper if you are experienced MVC developer. But Html helper helps the developer task easier.In short, Html helpers are similar to ASP.Net Web Controls except that they doesn't support viewstate,post back or eventmodel.
Some standard Html helpers are :
1. Html.ActionLink()
2. Html.BeginForm()
3. Html.TextArea()
4. Html.ListBox() etc. What is custom Html Helper ?
ASP.Net MVC provides a limited number of Html helpers by default. But we have the freedom to create our own custom html helpers. In order to create custom Html Helper we need to create an extension method on the Html helper class.
To build custom html helpers, we can also take the help of TagBuilder class which is a utility class which makes it easier to build HTML tags. Partial Views
Partial views are reusable components.In ASP.Net we have used UserControl and Custom controls to provide this functionality. Unlike ASP.Net server controls they wont use view state,post back or events to manage state information.They can be rendered inside a layout or regular view.
The syntax that render partial view is implemented as Html helper.
Html.partial helper method allows viewData/ViewBag objects to pass data between views or partial views.
@Html.Partial("_PartialViewExample")
//name of partial view without extension is the argument here
Sometimes we just need to write the content to Html response similar to Response.Write in ASP.Net Web forms. In that case we can go for Html.RenderPartial helper method.
@Html.RenderPartial("_PatialViewwithRenderPatial")
As a convention partial views name starts with underscore.If the partial views needs to be shared across views then it need to be created under Views/Shared folder.
Creating partial view is similar to views except we need to check the "Create Partial View" checkbox in the add view dialog box.
Really its useful . simple and good