MVC Tutorial
MVC Tutorial
MVC Tutorial
Prerequisites
Basic knowledge of .NET Framework 4.5, C#, and Visual Studio is
required.
The MVC architectural pattern has existed for a long time in software
engineering. All most all the languages use MVC with slight variation,
but conceptually it remains the same.
MVC Architecture
Request
Flow in MVC Architecture
As per the above figure, when a user enters a URL in the browser, it
goes to the webserver and routed to a controller. A controller
executes related view and models for that request and create the
response and sends it back to the browser.
Points to Remember
We are going to use ASP.NET MVC v5.2, and Visual Studio 2017
community edition, and .NET Framework 4.6 to create our first MVC
application.
Wait for some time till Visual Studio creates a simple MVC project
using the default template, as shown below.
MVC Project in Visual Studio
In this way, you can create your ASP.NET MVC 5 application using
Visual Studio 2017.
App_Data
The App_Data folder can contain application data files like
LocalDB, .mdf files, XML files, and other data related files. IIS will
never serve files from App_Data folder.
App_Start
The App_Start folder can contain class files that will be executed
when the application starts. Typically, these would be config files like
AuthConfig.cs, BundleConfig.cs, FilterConfig.cs, RouteConfig.cs etc.
MVC 5 includes BundleConfig.cs, FilterConfig.cs and RouteConfig.cs
by default. We will see the significance of these files later.
App_Start Folder
Content
The Content folder contains static files like CSS files, images, and
icons files. MVC 5 application includes bootstrap.css,
bootstrap.min.css, and Site.css by default.
Content Folder
Controllers
The Controllers folder contains class files for the controllers.
A Controller handles users' request and returns a response. MVC
requires the name of all controller files to end with "Controller". You
will learn about the controller in the next section.
Controller Folder
ADVERTISEMENT
fonts
The Fonts folder contains custom font files for your application.
Fonts folder
Models
The Models folder contains model class files. Typically model class
includes public properties, which will be used by the application to
hold and manipulate application data.
Scripts
The Scripts folder contains JavaScript or VBScript files for the
application. MVC 5 includes javascript files for bootstrap, jquery
1.10, and modernizer by default.
Scripts Folder
Views
The Views folder contains HTML files for the application. Typically
view file is a .cshtml file where you write HTML and C# or VB.NET
code.
The Views folder includes a separate folder for each controller. For
example, all the .cshtml files, which will be rendered by
HomeController will be in View > Home folder.
The Shared folder under the View folder contains all the views shared
among different controllers e.g., layout files.
View Folder
Global.asax
Global.asax file allows you to write code that runs in response to
application-level events, such as Application_BeginRequest,
application_start, application_error, session_start, session_end, etc.
Packages.config
Packages.config file is managed by NuGet to track what packages
and versions you have installed in the application.
Web.config
Web.config file contains application-level configurations.
Routing in MVC
In the ASP.NET Web Forms application, every URL must match with a
specific .aspx file. For example, a URL
http://domain/studentsinfo.aspx must match with the file
studentsinfo.aspx that contains code and markup for rendering a
response to the browser.
Routing is not specific to the MVC framework. It can be used with ASP.NET
Webform application or MVC application.
Route
Route defines the URL pattern and handler information. All the
configured routes of an application stored in RouteTable and will be
used by the Routing engine to determine appropriate handler class or
file for an incoming request.
The following figure illustrates the Routing process.
Routing in MVC
Configure a Route
Every MVC application must configure (register) at least one route
configured by the MVC framework by default. You can register a
route in RouteConfig class, which is
in RouteConfig.cs under App_Start folder. The following figure
illustrates how to configure a route in the RouteConfig class .
Configure Routes in MVC
As you can see in the above figure, the route is configured using
the MapRoute() extension method of RouteCollection, where name is
"Default", url pattern is "{controller}/{action}/{id}" and defaults
parameter for controller, action method and id parameter. Defaults
specify which controller, action method, or value of id parameter
should be used if they do not exist in the incoming request URL.
URL Pattern
The URL pattern is considered only after the domain name part in the
URL. For example, the URL
pattern "{controller}/{action}/{id}" would look like
localhost:1234/{controller}/{action}/{id}. Anything after
"localhost:1234/" would be considered as a controller name. The
same way, anything after the controller name would be considered as
action name and then the value of id parameter.
Routing in MVC
If the URL doesn't contain anything after the domain name, then the
default controller and action method will handle the request. For
example, http://localhost:1234 would be handled by
the HomeController and the Index() method as configured in the
default parameter.
ADVERTISEMENT
Multiple Routes
You can also configure a custom route using the MapRoute extension
method. You need to provide at least two parameters in MapRoute,
route name, and URL pattern. The Defaults parameter is optional.
Copy
routes.MapRoute(
name: "Student",
url: "students/{id}",
defaults: new { controller = "Student", action = "Index"}
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id
= UrlParameter.Optional }
);
}
}
Route Constraints
You can also apply restrictions on the value of the parameter by
configuring route constraints. For example, the following route
applies a limitation on the id parameter that the id's value must be
numeric.
Copy
routes.MapRoute(
name: "Student",
url: "student/{id}/{name}/{standardId}",
defaults: new { controller = "Student", action = "Index", id =
UrlParameter.Optional, name = UrlParameter.Optional, standardId =
UrlParameter.Optional },
constraints: new { id = @"\d+" }
);
Register Routes
Now, after configuring all the routes in the RouteConfig class, you
need to register it in the Application_Start() event in
the Global.asax so that it includes all your routes into
the RouteTable.
Copy
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
RouteConfig.RegisterRoutes(RouteTable.Routes);
}
}
Register Route
Points to Remember :
1. Routing plays important role in the MVC framework. Routing maps URL to
physical file or class (controller class in MVC).
2. Route contains URL pattern and handler information. URL pattern starts
after the domain name.
3. Routes can be configured in RouteConfig class. Multiple custom routes can
also be configured.
4. Route constraints apply restrictions on the value of parameters.
5. Route must be registered in Application_Start event in Global.ascx.cs file.
In ASP.NET MVC, every controller class name must end with a word
"Controller". For example, the home page controller name must
be HomeController, and for the student page, it must be
the StudentController. Also, every controller class must be located
in the Controller folder of the MVC folder structure.
MVC will throw "The resource cannot be found" error when you do not append
"Controller" to the controller class name.
Note:
Scaffolding is an automatic code generation framework for ASP.NET web
applications. Scaffolding reduces the time taken to develop a controller,
view, etc. in the MVC framework. You can develop a customized scaffolding
template using T4 templates as per your architecture and coding standards.
Ad
ding Controller
Ad
ding Controller
Example: Controller
Copy
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace MVC_BasicTutorials.Controllers
{
public class StudentController : Controller
{
// GET: Student
public ActionResult Index()
{
return View();
}
}
}
Now, we will return a dummy string from the Index action method of
above the StudentController. Changing the return type of Index
method from ActionResult to string and returning dummy string is
shown below. You will learn about the ActionResult in the next
section.
Example: Controller
Copy
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace MVC_BasicTutorials.Controllers
{
public class StudentController : Controller
{
// GET: Student
public string Index()
{
return "This is Index action method of
StudentController";
}
}
}
Co
ntroller
Points to Remember :
1. The Controller handles incoming URL requests. MVC routing sends
requests to the appropriate controller and action method based on URL and
configured Routes.
2. All the public methods in the Controller class are called Action
methods.
3. The Controller class must be derived from System.Web.Mvc.Controller
class.
4. The Controller class name must end with "Controller".
5. A new controller can be created using different scaffolding templates.
You can create a custom scaffolding template also.
Action method
In this section, you will learn about the action method of the
controller class.
Action Method
As you can see in the above figure, the Index() method is public, and
it returns the ActionResult using the View() method.
The View() method is defined in the Controller base class, which
returns the appropriate ActionResult.
Default Route
Copy
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}/{name}",
defaults: new { controller = "Home",
action = "Index",
id = UrlParameter.Optional
});
However, you can change the default action name as per your
requirement in the RouteConfig class.
ActionResult
MVC framework includes various Result classes, which can be
returned from an action method. The result classes represent
different types of responses, such as HTML, file, string, JSON,
javascript, etc. The following table lists all the result classes available
in ASP.NET MVC.
return RedirectToAction("Index");
}
[HttpDelete]
public ActionResult Delete(int id)
{
// delete student from the database whose id matches with
specified id
return RedirectToAction("Index");
}
Points to Remember :
1. All the public methods in the Controller class are called Action
methods.
2. The Action method has the following restrictions.
- Action method must be public. It cannot be private or protected.
- Action method cannot be overloaded.
- Action method cannot be a static method.
3. ActionResult is a base class of all the result type which returns from
Action method.
4. The base Controller class contains methods that returns appropriate
result type e.g. View(), Content(), File(), JavaScript() etc.
5. The Action method can include Nullable type parameters.
Action Selectors
Action selector is the attribute that can be applied to the action
methods. It helps the routing engine to select the correct action
method to handle a particular request. MVC 5 includes the following
action selector attributes:
1. ActionName
2. NonAction
3. ActionVerbs
ActionName
The ActionName attribute allows us to specify a different action name
than the method name, as shown below.
[ActionName("Find")]
public ActionResult GetById(int id)
{
// get student from the database
return View();
}
}
NonAction
Use the NonAction attribute when you want public method in a
controller but do not want to treat it as an action method.
Example: NonAction
Copy
public class StudentController : Controller
{
public string Index()
{
return "This is Index action method of StudentController";
}
[NonAction]
public Student GetStudent(int id)
{
return studentList.Where(s => s.StudentId ==
id).FirstOrDefault();
}
}
GET To retrieve the information from the server. Parameters will be appended in the query string.
HEAD Identical to GET except that server do not return the message body.
OPTIONS It represents a request for information about the communication options supported by the web server.
Copy
[HttpPost]
public ActionResult PostAction() // handles POST requests by
default
{
return View("Index");
}
[HttpPut]
public ActionResult PutAction() // handles PUT requests by default
{
return View("Index");
}
[HttpDelete]
public ActionResult DeleteAction() // handles DELETE requests by
default
{
return View("Index");
}
[HttpHead]
public ActionResult HeadAction() // handles HEAD requests by
default
{
return View("Index");
}
[HttpOptions]
public ActionResult OptionsAction() // handles OPTION requests by
default
{
return View("Index");
}
[HttpPatch]
public ActionResult PatchAction() // handles PATCH requests by
default
{
return View("Index");
}
}
Example: AcceptVerbs
Copy
[AcceptVerbs(HttpVerbs.Post | HttpVerbs.Get)]
public ActionResult GetAndPostAction()
{
return RedirectToAction("Index");
}
In the Add New Item dialog box, enter the class name Student and
click Add.
Cre
ate Model Class
This will add a new Student class in model folder. We want this model
class to store id, name, and age of the students. So, we will have to
add public properties for Id, Name, and Age, as shown below.
Copy
The model class can be used in the view to populate the data, as well
as sending data to the controller.
A controller can have one or more action methods, and each action
method can return a different view. In short, a controller can render
one or more views. So, for easy maintenance, the MVC framework
requires a separate sub-folder for each controller with the same
name as a controller, under the Views folder.
Note:
The Shared folder contains views, layout views, and partial views, which will be
shared among multiple controllers.
.vbhtml Visual Basic Razor view. Supports Visual Basic code with html tags.
Creating a View
You can create a view for an action method directly from it by right
clicking inside an action method and select Add View...
This will open the Add View dialogue box, shown below. It's good
practice to keep the view name the same as the action method name
so that you don't have to explicitly specify the view name in the
action method while returning the view.
Ad
d a View
Views\Student\Index.cshtml:
Copy
@model IEnumerable<MVC_BasicTutorials.Models.Student>
@{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Index</h2>
<p>
@Html.ActionLink("Create New", "Create")
</p>
<table class="table">
<tr>
<th>
@Html.DisplayNameFor(model => model.StudentName)
</th>
<th>
@Html.DisplayNameFor(model => model.Age)
</th>
<th></th>
</tr>
</table>
The above Index view would look as below when we run the
application.
Ind
ex View
Note:
Example: StudentController
Copy
Copy
Copy
@model IEnumerable<MVC_BasicTutorials.Models.Student>
@{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Index</h2>
<p>
@Html.ActionLink("Create New", "Create")
</p>
<table class="table">
<tr>
<th>
@Html.DisplayNameFor(model => model.StudentName)
</th>
<th>
@Html.DisplayNameFor(model => model.Age)
</th>
<th></th>
</tr>
</table>
Copy
return View(studentList);
}
}
Try it
As you can see in the above code, we have created a list of student
objects for an example purpose (in real-life application, you can fetch
it from the database). We then pass this list object as a parameter in
the View() method. The View() method is defined in the base
Controller class, which automatically binds a model object to a view.
Now, you can run the MVC project by pressing F5 and navigate
to http://localhost/Student. You will see the following view in the
browser.
Bind Query String to an Action Method
Parameters in MVC
Here, you will learn about to bind a model object to an action method
parameters in the ASP.NET MVC application.
The model binding refers to converting the HTTP request data (from
the query string or form collection) to an action method parameters.
These parameters can be of primitive type or complex type.
Model
Binding
You can also have multiple parameters in the action method with
different data types. Query string values will be converted into
parameters based on the matching names.
Copy
return View();
}
Copy
Now, you can create an action method which includes the Student
type parameter. In the following example, Edit action method
(HttpPost) includes Student type parameter.
Copy
[HttpPost]
public ActionResult Edit(Student std)
{
var id = std.StudentId;
var name = std.StudentName;
var age = std.Age;
var standardName = std.standard.StandardName;
return RedirectToAction("Index");
}
Thus, the MVC framework will automatically map Form collection
values to the Student type parameter when the form submits an
HTTP POST request to the Edit() action method, as shown below.
FormCollection
You can also include the FormCollection type parameter in the action
method instead of a complex type to retrieve all the values from view
form fields, as shown below.
Mo
del Binding to FormCollection
Bind Attribute
ASP.NET MVC framework also enables you to specify which properties
of a model class you want to bind. The [Bind] attribute will let you
specify the exact properties of a model should include or exclude in
binding.
Copy
[HttpPost]
public ActionResult Edit([Bind(Include = "StudentId, StudentName")]
Student std)
{
var name = std.StudentName;
return RedirectToAction("Index");
}
Copy
[HttpPost]
public ActionResult Edit([Bind(Exclude = "Age")] Student std)
{
var name = std.StudentName;
return RedirectToAction("Index");
}
Model
Binding in ASP.NET MVC
The following figure describes how the edit functionality would work
in ASP.NET MVC application.
Editing Steps in ASP.NET MVC App
1. The user clicks on the Edit link in the student list view, which will
send the HttpGET request http://localhost/student/edit/{Id} with
corresponding Id parameter in the query string. This request will be
handled by the HttpGET action method Edit(). (by default action
method handles the HttpGET request if no attribute specified)
3. The user can edit the data and click on the Save button in the Edit
view. The Save button will send a HttpPOST
request http://localhost/Student/Edit with the Form data collection.
4. The HttpPOST Edit action method in StudentController will finally
update the data into the database and render an Index page with the
refreshed data using the RedirectToAction method as a fourth step.
Copy
namespace MVCTutorials.Controllers
{
public class Student
{
public int StudentId { get; set; }
[Display( Name="Name")]
public string StudentName { get; set; }
Step: 1
Step 2:
Copy
using MVCTutorials.Models;
namespace MVCTutorials.Controllers
{
public class StudentController : Controller
{
static IList<Student> studentList = new List<Student>{
new Student() { StudentId = 1, StudentName = "John",
Age = 18 } ,
new Student() { StudentId = 2, StudentName = "Steve",
Age = 21 } ,
new Student() { StudentId = 3, StudentName = "Bill",
Age = 25 } ,
new Student() { StudentId = 4, StudentName = "Ram" ,
Age = 20 } ,
new Student() { StudentId = 5, StudentName = "Ron" ,
Age = 31 } ,
new Student() { StudentId = 4, StudentName = "Chris" ,
Age = 17 } ,
new Student() { StudentId = 4, StudentName = "Rob" ,
Age = 19 }
};
// GET: Student
public ActionResult Index()
{
//fetch students from the DB using Entity Framework here
return View(std);
}
}
}
The HttpGet Edit() action method must perform two tasks. First, it
should fetch a student data from the underlying data source,
whose StudentId matches the parameter Id. Second, it should render
the Edit view with the data, so that the user can edit it.
Step 3:
Sel
ect Edit Template and Model
Click Add button to generate the Edit.cshtml view
under /View/Student folder, as shown below.
/View/Student/Edit.cshtml
Copy
@model MVCTutorials.Models.Student
@{
ViewBag.Title = "Edit";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Edit</h2>
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Student</h4>
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger"
})
@Html.HiddenFor(model => model.StudentId)
<div class="form-group">
@Html.LabelFor(model => model.StudentName, htmlAttributes:
new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.StudentName, new
{ htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.StudentName,
"", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Age, htmlAttributes: new
{ @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Age, new
{ htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Age, "", new
{ @class = "text-danger"< })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-
default" />
</div>
</div>
</div>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>
You can now edit the data and click on the Save button. The Save
button should send the HttpPOST request because we need to submit
the form data as a part of the request body as a Student object.
Step 4:
using MVCTutorials.Models;
namespace MVCTutorials.Controllers
{
public class StudentController : Controller
{
IList<Student> studentList = new List<Student>() {
new Student(){ StudentId=1, StudentName="John",
Age = 18 },
new Student(){ StudentId=2, StudentName="Steve",
Age = 21 },
new Student(){ StudentId=3, StudentName="Bill",
Age = 25 },
new Student(){ StudentId=4, StudentName="Ram", Age
= 20 },
new Student(){ StudentId=5, StudentName="Ron", Age
= 31 },
new Student(){ StudentId=6, StudentName="Chris",
Age = 17 },
new Student(){ StudentId=7, StudentName="Rob", Age
= 19 }
};
// GET: Student
public ActionResult Index()
{
return View(studentList.OrderBy(s =>
s.StudentId).ToList());
}
return View(std);
}
[HttpPost]
public ActionResult Edit(Student std)
{
//update student in DB using EntityFramework in real-life
application
return RedirectToAction("Index");
}
}
}
Razor Syntax
Razor is one of the view engines supported in ASP.NET MVC. Razor
allows you to write a mix of HTML and server-side code using C# or
Visual Basic. Razor view with visual basic syntax has .vbhtml file
extension and C# syntax has .cshtml file extension.
Inline expression
Start with @ symbol to write server-side C# or VB code with HTML
code. For example, write @Variable_Name to display the value of a
server-side variable, e.g., DateTime.Now returns the current date
and time. So, write @DateTime.Now to display the current date and
time, as shown below. A single line expression does not require a
semicolon at the end of the expression.
C# Razor Syntax
Copy
<h1>Razor syntax demo</h1>
<h2>@DateTime.Now.ToShortDateString()</h2>
Output:
Razor syntax demo
08-09-2014
if-else condition
Write if-else condition starting with @ symbol. The if-else code block
must be enclosed in braces { }, even for a single statement.
for loop
Example: for loop in Razor
Copy
@for (int i = 0; i < 5; i++) {
@i.ToString() <br />
}
Output:
0
1
2
3
4
Model
Use @model to use model object anywhere in the view.
<h2>Student Detail:</h2>
<ul>
<li>Student Id: @Model.StudentId</li>
<li>Student Name: @Model.StudentName</li>
<li>Age: @Model.Age</li>
</ul>
Output:
Student Detail:
- Student Id: 1
- Student Name: John
- Age: 18
Declare Variables
Declare a variable in a code block enclosed in brackets and then use
those variables inside HTML with @ symbol.
Example: Variable in Razor
Copy
@{
string str = "";
if(1 > 0)
{
str = "Hello World!";
}
}
<p>@str</p>
Output:
Hello World!
HTML Helpers
Here, you will learn what HTML helpers are and how to use them in
the razor view.
Strongly Typed
Extension Method Method Html Control
Html.ActionLink() NA <a></a>
Html.Editor() Html.EditorFor() Generates Html controls based on data type of specified model property e.g.
textbox for string property, numeric field for int, double or other numeric type.
Copy
Html.TextBoxFor()
The TextBoxFor<TModel, TProperty>() is the generic extension
method that creates <input type="text"> control. The first type
parameter is for the model class, and second type parameter is for
the property.
TextBoxFor() Signature
Copy
Copy
@model Student
Html Result:
<input id="StudentName" name="StudentName" type="text" value="" />
Copy
@model Student
Html.TextBox()
The TextBox() method creates <input type="text" > HTML control
with the specified name, value, and other attributes.
TextBoxFor() Signature
Copy
Copy
@model Student
@Html.TextBox("StudentName")
Html Result:
Copy
Html.TextAreaFor()
The TextAreaFor<TModel, TProperty>() is the generic extension method that
creates <textarea></textarea> control.
TextAreaFor() Signature
Copy
@model Student
@model Student
Html Result:
Html.TextArea()
The Html.TextArea() method creates a <textarea> HTML control with specified
name, value and html attributes.
Copy
@model Student
@Html.TextArea("Description", "This is dummy description.", new
{ @class = "form-control" })
Html Result:
Copy
Html.CheckBoxFor()
The CheckBoxFor<TModel, TProperty>() extension method
generates <input type="checkbox"> control for the model property
specified using a lambda expression.
Copy
@model Student
@Html.CheckBoxFor(m => m.isActive)
Html Result:
<input data-val="true"
data-val-required="The isActive field is required."
id="isActive"
name="isActive"
type="checkbox"
value="true" />
Notice that it has generated an additional hidden field with the same
name and value=false. When you submit a form with a checkbox,
the value is posted only if a checkbox is checked. So, if you leave the
checkbox unchecked, then nothing will be sent to the server.
Sometimes, you would want false to be sent to the server. Because,
an hidden input has the same name, it will send false to the server if
checkbox is unchecked.
ADVERTISEMENT
Html.CheckBox()
The Html.CheckBox() is a loosely typed method which generates
a <input type="checkbox" > with the specified
name, isChecked boolean, and HTML attributes.
Copy
@Html.CheckBox("isActive", true)
Html Result:
<input checked="checked"
id="isActive"
name="isActive"
type="checkbox"
value="true" />
Create Radio buttons in ASP.NET MVC
Learn how to generate radio button control using the HtmlHelper in
razor view in this section.
Copy
Html.RadioButtonFor()
The Html.RadioButtonFor<TModel, TProperty>() extension method is
a strongly typed extension method. It generates <input
type="radio"> control for the property specified using a lambda
expression.
Copy
@model Student
<input checked="checked"
id="Gender"
name="Gender"
type="radio"
value="Male" />
<input id="Gender"
name="Gender"
type="radio"
value="Female" />
ADVERTISEMENT
RadioButton()
The Html.RadioButton() method creates an radio button element
with a specified name, isChecked boolean and html attributes.
Copy
Male: @Html.RadioButton("Gender","Male")
Female: @Html.RadioButton("Gender","Female")
Html Result:
Male: <input checked="checked"
id="Gender"
name="Gender"
type="radio"
value="Male" />
Copy
Html.DropDownListFor()
The Html.DropDownListFor<TModel,TProperty> extension method is a
strongly typed extension method generates <select> element for the
property specified using a lambda expression.
Copy
@using MyMVCApp.Models
@model Student
ADVERTISEMENT
Html.DropDownList()
The Html.DropDownList() method generates a <select> element with
specified name, list items and html attributes.
Copy
@using MyMVCApp.Models
@model Student
@Html.DropDownList("StudentGender",
new SelectList(Enum.GetValues(typeof(Gender))),
"Select Gender",
new { @class = "form-control" })
Html Result:
Copy
Html.HiddenFor()
The Html.HiddenFor<TModel, TProperty> extension method is a
strongly typed extension method generates a hidden input element
for the model property specified using a lambda expression.
Copy
@model Student
<input data-val="true"
data-val-number="The field StudentId must be a number."
data-val-required="The StudentId field is required."
id="StudentId"
name="StudentId"
type="hidden"
value="" />
Html.Hidden()
The Html.Hidden() method generates a input hidden field element
with specified name, value and html attributes.
Copy
@model Student
@Html.Hidden("StudentId")
Html Result:
<input id="StudentId"
name="StudentId"
type="hidden"
value="1" />
Html.PasswordFor()
The Html.PasswordFor<TModel,TProperty>() extension method is a
strongly typed extension method. It generates a <input
type="password"> element for the model object property specified
using a lambda expression.
Copy
@model User
ADVERTISEMENT
Html.Password()
The Html.Password() method generates a input password element
with specified name, value and html attributes.
Visit docs.microsoft.com to know all the overloads of Password()
method.
Copy
@model User
@Html.Password("Password")
Html Result:
<input
id="Password"
name="Password"
type="password"
value="" />
We will use the following model class with the Display() and
DisplayFor() method.
Copy
Html.DisplayFor()
The DisplayFor() helper method is a strongly typed extension
method. It generates a html string for the model object property
specified using a lambda expression.
Copy
@model Student
"Steve"
Display()
The Html.Display() is a loosely typed method which generates a
string in razor view for the specified property of model.
Copy
@Html.Display("StudentName")
Html Result:
"Steve"
Create Label in ASP.Net MVC
The HtmlHelper class includes two extension methods to generate
HTML label element: Label() and LabelFor().
Copy
Html.LabelFor()
The Html.LabelFor<TModel,TProperty>() helper method is a strongly
typed extension method. It generates a html label element for the
model object property specified using a lambda expression.
Copy
@model Student
<label for="StudentName">Name</label>
Label()
The Html.Label() method generates a <label> element for a
specified property of model object.
Copy
@Html.Label("StudentName")
Html Result:
<label for="StudentName">Name</label>
You can specify another label text instead of property name as shown
below.
Copy
@Html.Label("StudentName","Student Name")
Html Result:
Copy
Html.EditorFor()
The Html.EditorFor() method is a strongly typed method. It requires
the lambda expression to specify a property of the model object.
Copy
@model Student
StudentId: @Html.EditorFor(m => m.StudentId) <br />
Student Name: @Html.EditorFor(m => m.StudentName) <br />
Age: @Html.EditorFor(m => m.Age)<br />
Password: @Html.EditorFor(m => m.Password)<br />
isNewlyEnrolled: @Html.EditorFor(m => m.isNewlyEnrolled)<br />
DoB: @Html.EditorFor(m => m.DoB)
Html Result:
Html.Editor()
The Html.Editor() method requires a string parameter to specify the
property name. It creats a HTML element based on the datatype of
the specified property, same as EditorFor() method.
Copy
StudentId: @Html.Editor("StudentId")
Student Name: @Html.Editor("StudentName")
Age: @Html.Editor("Age")
Password: @Html.Editor("Password")
isNewlyEnrolled: @Html.Editor("isNewlyEnrolled")
Gender: @Html.Editor("Gender")
DoB: @Html.Editor("DoB")
You may handle all possible exceptions in the action methods using
try-catch blocks. However, there can be some unhandled exceptions
that you want to log and display custom error messages or custom
error pages to users.
De
fault Error Page in MVC
1. Using <customErrors> element in web.config
2. Using HandleErrorAttribute
3. Overriding Controller.OnException method
4. Using Application_Error event of HttpApplication
HandleErrorAttribute
The HandleErrorAttribute is an attribute that can be used to handle
exceptions thrown by an action method or a controller. You can use it
to display a custom view on a specific exception occurred in an action
method or in an entire controller.
Note:
The HandleErrorAttribute attribute can only be used to handle the exception
with status code 500. Also, it does not provide a way to log exceptions.
In order to use this attribute, you must
add HandleErrorAttribute filter in
the FilterConfig.RegisterGlobalFilters() method and also, set the
mode attribute to On <customErrors mode="On"> in web.config, as we
did for the customErrors section above.
Example: HandleErrorAttribute
Copy
public class HomeController : Controller
{
[HandleError]
public ActionResult Contact()
{
string msg = null;
ViewBag.Message = msg.Length;
return View();
}
}
Above, we configured [HandleError] attribute on
the Contact() action method. It will display Error.cshtml view from
the Shared folder when an exception occurs. The [HandleError] set
the Error.cshtml view as default view for any exceptions.
return View();
}
}
return View();
}
//Redirect to action
filterContext.Result = RedirectToAction("Error",
"InternalError");
Example:
Copy
public class MvcApplication : System.Web.HttpApplication
{
//other code removed for clarity
Recommendation
In most web applications, you should ideally log the exceptions and
also show appropriate error messages or pages to the users. So, it is
recommended to use the global Application_Error event to log all
the exceptions along with <customErrors> element in web.config to
redirect it to appropriate pages.
The following table lists all the data annotation attributes which can
be used for validation.
Attribute Usage
StringLength Specifies the minimum and maximum length of characters that are allowed in a string type property.
Range Specifies the numeric range constraints for the value of a property.
RegularExpression Specifies that a property value must match the specified regular expression.
MaxLength Specifies the maximum length of array or string data allowed in a property.
MinLength Specifies the minimum length of array or string data allowed in a property.
Copy
Copy
[Required]
public string StudentName { get; set; }
[Range(10, 20)]
public int Age { get; set; }
}
Copy
return View(stud);
}
[HttpPost]
public ActionResult Edit(Student std)
{
if (ModelState.IsValid) { //checking model state
//update student to db
return RedirectToAction("Index");
}
return View(std);
}
}
Copy
@model MVC_BasicTutorials.Models.Student
@{
ViewBag.Title = "Edit";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Edit</h2>
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Student</h4>
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger"
})
@Html.HiddenFor(model => model.StudentId)
<div class="form-group">
@Html.LabelFor(model => model.StudentName, htmlAttributes:
new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.StudentName, new
{ htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.StudentName,
"", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Age, htmlAttributes: new
{ @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Age, new
{ htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Age, "", new
{ @class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-
default" />
</div>
</div>
</div>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>
Val
idation
Signature:
Copy
Example: ValidationMessageFor
Copy
@model Student
The above code will generate the following HTML when you run it.
Html Result:
Copy
<input id="StudentName"
name="StudentName"
type="text"
value="" />
Copy
Copy
Copy
@model Student
It is recommended to
use ValidationMessageFor() than ValidationMessage() because it is
strongly typed and so performs fast and less error pron.
Copy
Example: ValidationMessageFor
Copy
@model Student
@Html.ValidationSummary(false, "", new { @class = "text-danger" })
Here, we will display a message if a student's name already exists in the database. So,
in the HTTP Post action method, check the name in the database and add error message
in the ModelState dictionary if the name already exists, as shown below.
Copy
return View(stud);
}
[HttpPost]
public ActionResult Edit(Student std)
{
if (ModelState.IsValid) { //checking model state
if(nameAlreadyExists)
{
//adding error message to ModelState
ModelState.AddModelError("name", "Student Name Already
Exists.");
return View(std);
}
return RedirectToAction("Index");
}
return View(std);
}
}
The layout view allows you to define a common site template, which
can be inherited in multiple views to provide a consistent look and
feel in multiple pages of an application. The layout view eliminates
duplicate coding and enhances development speed and easy
maintenance. The layout view for the above sample UI would contain
a Header, Left Menu, Right bar, and Footer sections. It has a
placeholder for the center section that changes dynamically, as
shown below.
Layout View
The layout view has the same extension as other views, .cshtml or
.vbhtml. Layout views are shared with multiple views, so it must be
stored in the Shared folder. By default, a layout
view _Layout.cshtml is created when you Create MVC
application using Visual Studio, as shown below.
Layout Views in Shared Folder
_Layout.cshtml:
Copy
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-
scale=1.0">
<title>@ViewBag.Title - My ASP.NET Application</title>
@Styles.Render("~/Content/css")
@Scripts.Render("~/bundles/modernizr")
</head>
<body>
<div class="navbar navbar-inverse navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-
toggle="collapse" data-target=".navbar-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
@Html.ActionLink("Application name", "Index", "Home",
new { area = "" }, new { @class = "navbar-brand" })
</div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li>@Html.ActionLink("Home", "Index", "Home")</li>
<li>@Html.ActionLink("About", "About",
"Home")</li>
<li>@Html.ActionLink("Contact", "Contact",
"Home")</li>
</ul>
</div>
</div>
</div>
<div class="container body-content">
@RenderBody()
<hr />
<footer>
<p>© @DateTime.Now.Year - My ASP.NET Application</p>
</footer>
</div>
@Scripts.Render("~/bundles/jquery")
@Scripts.Render("~/bundles/bootstrap")
@RenderSection("scripts", required: false)
</body>
</html>
As you can see, the layout view contains HTML Doctype, head, and
body tags. The only difference is a call
to RenderBody() and RenderSection() methods. The child views will
be displayed where the RenderBody() is called.
ADVERTISEMENT
Se
tting Layout View in _ViewStart.cshtml
Index.cshtml
Copy
@{
ViewBag.Title = "Home Page";
Layout = "~/Views/Shared/_myLayoutPage.cshtml";
}
<div class="jumbotron">
<h1>ASP.NET</h1>
<p class="lead">ASP.NET is a free web framework for building great
Web sites and Web applications using HTML, CSS and JavaScript.</p>
<p><a href="http://asp.net" class="btn btn-primary btn-lg">Learn
more »</a></p>
</div>
<div class="row">
<div class="col-md-4">
<h2>Getting started</h2>
<p>
ASP.NET MVC gives you a powerful, patterns-based way to
build dynamic websites that
enables a clean separation of concerns and gives you full
control over markup
for enjoyable, agile development.
</p>
<p><a class="btn btn-default"
href="http://go.microsoft.com/fwlink/?LinkId=301865">Learn more
»</a></p>
</div>
<div class="col-md-4">
<h2>Get more libraries</h2>
<p>NuGet is a free Visual Studio extension that makes it easy
to add, remove, and update libraries and tools in Visual Studio
projects.</p>
<p><a class="btn btn-default"
href="http://go.microsoft.com/fwlink/?LinkId=301866">Learn more
»</a></p>
</div>
<div class="col-md-4">
<h2>Web Hosting</h2>
<p>You can easily find a web hosting company that offers the
right mix of features and price for your applications.</p>
<p><a class="btn btn-default"
href="http://go.microsoft.com/fwlink/?LinkId=301867">Learn more
»</a></p>
</div>
</div>
Copy
Rendering Methods
ASP.NET MVC layout view renders child views using the following
methods.
Method Description
RenderBody() Renders the portion of the child view that is not within a named section. Layout
view must include the RenderBody() method.
RenderSection(string name) Renders a content of named section and specifies whether the section is
required.
_myLayoutPage.cshtml
Copy
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>@ViewBag.Title</title>
</head>
<body>
<div>
@RenderBody()
</div>
</body>
</html>
Now, let's add the common <footer> tag with
the RenderSection("footer",true) method, as shown below. Please
notice that we made this section as required. It means any view that
uses the _myLayoutPage as its layout view must include a footer
section.
Copy
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>@ViewBag.Title</title>
@Styles.Render("~/Content/css")
@Scripts.Render("~/bundles/modernizr")
</head>
<body>
<div>
@RenderBody()
</div>
<footer class="panel-footer">
@RenderSection("footer", true)
</footer>
</body>
</html>
Index.cshtml
Copy
@{
ViewBag.Title = "Home Page";
Layout = "~/Views/Shared/_myLayoutPage.cshtml";
}
<h2>Index</h2>
Index.cshtml
Copy
@{
ViewBag.Title = "Home Page";
Layout = "~/Views/Shared/_myLayoutPage.cshtml";
}
<h2>Index</h2>
<div class="row">
<div class="col-md-4">
<p>This is body.</p>
</div>
@section footer{
<p class="lead">
This is footer section.
</p>
}
</div>
Now, run the application, and you will see that the Index view will be
displayed in the RenderBody() method, and the footer section will be
displayed in the RenderSection("footer", true), as shown below.
Thus, you can create a new layout view with a body and different
sections.
Let's create a partial view for the following menu, so that we can use
the same menu in multiple layout views without rewriting the same
code everywhere.
Partial View
You can now cut the above code for the navigation bar and paste it
in _MenuBar.cshtml as shown below:
_MenuBar.cshtml
Copy
Thus, you can create a new partial view. Let's see how to render
partial view.
ADVERTISEMENT
Html.Partial()
The @Html.Partial() method renders the specified partial view. It
accepts partial view name as a string parameter and
returns MvcHtmlString. It returns an HTML string, so you have a
chance of modifying the HTML before rendering.
_MenuBar
Copy
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-
scale=1.0">
<title>@ViewBag.Title - My ASP.NET Application</title>
@Styles.Render("~/Content/css")
@Scripts.Render("~/bundles/modernizr")
</head>
<body>
@Html.Partial("_MenuBar")
Html.RenderPartial()
The @html.RenderPartial() method is the same as
the @html.Partial() method except that it writes the resulted HTML
of a specified partial view into an HTTP response stream directly. So,
you can modify it's HTML before render.
Example: Html.RenderPartial()
Copy
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-
scale=1.0">
<title>@ViewBag.Title - My ASP.NET Application</title>
@Styles.Render("~/Content/css")
@Scripts.Render("~/bundles/modernizr")
</head>
<body>
@{
Html.RenderPartial("_MenuBar");
}
<div class="container body-content">
@RenderBody()
<hr />
<footer>
<p>© @DateTime.Now.Year - My ASP.NET Application</p>
</footer>
</div>
@Scripts.Render("~/bundles/jquery")
@Scripts.Render("~/bundles/bootstrap")
@RenderSection("scripts", required: false)
</body>
</html>
Html.RenderAction()
The @html.RenderAction() method executes the specified action
method and renders the result. The specified action method must be
marked with the [ChildActionOnly] attribute and return
the PartialViewResult using the PartialView() method.
Copy
public class HomeController : Controller
{
[ChildActionOnly]
public ActionResult RenderMenu()
{
return PartialView("_MenuBar");
}
}
Example: Html.RenderPartial()
Copy
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-
scale=1.0">
<title>@ViewBag.Title - My ASP.NET Application</title>
@Styles.Render("~/Content/css")
@Scripts.Render("~/bundles/modernizr")
</head>
<body>
@{
Html.RenderAction("RenderMenu", "Home");
}
<div class="container body-content">
@RenderBody()
<hr />
<footer>
<p>© @DateTime.Now.Year - My ASP.NET Application</p>
</footer>
</div>
@Scripts.Render("~/bundles/jquery")
@Scripts.Render("~/bundles/bootstrap")
@RenderSection("scripts", required: false)
</body>
</html>
You will see the following result in the browser, irrespective of the
rendering method you use.
In this way, you can create a partial view for different portions of the
web page in ASP.NET MVC application.
Note:
ViewBag only transfers data from controller to view, not visa-versa. ViewBag
values will be null if redirection occurs.
return View();
}
}
}
Index.cshtml
Copy
<label>Total Students:</label> @ViewBag.TotalStudents
Output:
Total Students: 5
ViewBag Limitations
ViewBag doesn't require typecasting while retrieving values from it.
This can throw a run-time exception if the wrong method is used on
the value.
ViewBag is a dynamic type and skips compile-time checking. So,
ViewBag property names must match in controller and view while
writing it manually.
Note:
ViewData only transfers data from controller to view, not vice-versa. It is
valid only during the current request.
ViewData["students"] = studentList;
return View();
}
return View();
}
return View();
}
Points to Remember :
The following example shows how to transfer data from one action
method to another using TempData.
Example: TempData
Copy
return View();
}
if(TempData.ContainsKey("name"))
name = TempData["name"].ToString(); // returns "Bill"
return View();
}
return View();
}
}
Example: TempData
Copy
return View();
}
return View();
}
return View();
}
}
Above, we added data in the TempData in the Index() action
method. So, we can access it in the Index.cshtml view, as shown
below. Because we have accessed it in the index view first, we
cannot access it anywhere else.
Index.cshtml
Copy
@{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
@TempData["name"]
ADVERTISEMENT
You can also transfer data from a view to controller, as shown below.
Index.cshtml
Copy
@{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
@{
TempData["name"] = "Steve";
}
Example: TempData
Copy
return View();
}
return View();
}
}
The following example shows how to retain TempData value for the
subsequent requests even after accessing it.
Example: TempData.Keep()
Copy
if(TempData.ContainsKey("name"))
name = TempData["name"] as string;
TempData.Keep("name"); // Marks the specified key in the
TempData for retention.
return View();
}
if(TempData.ContainsKey("name"))
data = TempData["name"] as string;
return View();
}
}
ASP.NET MVC Filter is a custom class where you can write custom
logic to execute before or after an action method executes. Filters
can be applied to an action method or controller in a declarative or
programmatic way. Declarative means by applying a filter attribute
to an action method or controller class and programmatic means by
implementing a corresponding interface.
MVC provides different types of filters. The following table list filter
types, built-in filters, and interface that must be implemented to
create custom filters.
Filter Type Description Built-in Filter Interface
Authorization Performs authentication and authorizes before executing an action [Authorize], IAuthorizationFilter
filters method. [RequireHttps]
Action filters Performs some operation before and after an action method IActionFilter
executes.
Result filters Performs some operation before or after the execution of the [OutputCache] IResultFilter
view.
Exception filters Performs some operation if there is an unhandled exception [HandleError] IExceptionFilter
thrown during the execution of the ASP.NET MVC pipeline.
Copy
[HandleError]
public class HomeController : Controller
{
public ActionResult Index()
{
//throw exception for demo
throw new Exception("This is unhandled exception");
return View();
}
Copy
Now, if you run the application, you would get the following error
page because we throw an exception in the Index() action method
for the demo purpose.
ADVERTISEMENT
Register Filters
Filters can be applied at three levels.
Copy
Copy
[HandleError]
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
}
Action Method Filters
One or more filters can also applied to an individual action method.
The following filter applied only on the Index() action method.
Copy
Example: ActionFilter
Copy
[OutputCache(Duration=100)]
public ActionResult Index()
{
return View();
}
The above example will show the following output when browing
to http://localhost/home request.
Output:
In this way, you can keep track of the action methods execution
using action filters.
Bundling and Minification
Bundling and minification techniques were introduced in MVC 4 to
improve request load time. Bundling allows us to load the bunch of
static files from the server in a single HTTP request.
Loading
script files in separate requests
In the above figure, the browser sends two separate requests to load
two different JavaScript file MyJavaScriptFile-
1.js and MyJavaScriptFile-2.js.
Minification
Minification technique optimizes script or CSS file size by removing
unnecessary white space and comments and shortening variable
names to one character.
Example: JavaScript
Copy
sayHello = function(name){
//this is comment
var msg = "Hello" + name;
alert(msg);
}
Copy
sayHello=function(n){var t="Hello"+n;alert(t)}
Bundle Types
MVC 5 includes following bundle classes
in System.web.Optimization namespace:
Copy
using System.Web;
using System.Web.Optimization;
Copy
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-
scale=1.0">
<title>@ViewBag.Title</title>
@Scripts.Render("~/bundles/bootstrap")
</head>
<body>
@*html code removed for clarity *@
</body>
</html>
Now, when you run the application in the release mode, you will see
the bundle is created and loaded in a single request.
Include a Directory in Bundle
Use the IncludeDirectory method to add all the files under a
particular directory in a bundle, as shown below.
ScriptBundle Example:
Copy
Using Wildcards
Most third party JavaScript files include a version in the name of the
script file. For example, jQuery includes the version in the file name.
The wildcard {version} will automatically pick up an available version
file.
Copy
Using CDN
You can also create a bundle of the files from the Content Delivery
Network (CDN), as shown below.
Copy
public class BundleConfig
{
public static void RegisterBundles(BundleCollection bundles)
{
var cdnPath = "http://ajax.aspnetcdn.com/ajax/jQuery/jquery-
1.7.1.min.js";
The following example shows how to combine multiple CSS files into
a bundle.
Copy
}
}
Copy
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-
scale=1.0">
<title>@ViewBag.Title - My ASP.NET Application</title>
@Styles.Render("~/bundles/css")
</head>
<body>
@*html code removed for clarity *@
</body>
</html>
Now, when you run the application in the release mode, you will see
the bundle is created and loaded in a single request.
You can use the IncludeDirectory() method, version
wildcard {version}, and CDN path the same way as ScriptBundle .
Learn how to set image path in StyleBundle .
Note:
Creating an Area
You can create an area by right-clicking on the project in the solution
explorer -> Add -> Area.., as shown below.
Enter the name of an area in the Add Area dialogue box and click on
the Add button.
Copy
So in this way, you can create and maintain multiple areas for the
large application.