Objectives
Objectives
Objectives
Web applications have revolutionized the way business is conducted. These applications enable organizations to
share and access information from anywhere, anytime. This has majorly moved the focus of application
development from desktop applications to Web applications. Today, one of the most popular server-side
technologies used for developing Web applications is ASP.NET.
This chapter introduces the basics of Web application development. It also discusses the layers, architecture, and
different ways of scripting a Web application. In addition, it discusses the different types of Web development
platforms and explains the ASP.NET MVC platform in detail.
Objectives
Prior to the evolution of the Internet, organizations could deliver only limited information to their prospective
clients by using the existing communication media. However, with the inception of the Internet, organizations
found a new medium to reach a larger range of people, irrespective of their geographical locations. Therefore,
organizations increasingly became dependent on the Internet for sharing and accessing information. This resulted
in changing the focus of application development from desktop applications to Web applications.
Web applications are programs that are executed on a Web server and accessed from a Web browser. These
applications enable organizations to share and access information on the Internet and corporate intranets. This
information can be accessed from anywhere, anytime. In addition, Web applications can support online
commercial transactions, popularly known as e-commerce. An online store accessed through a Web browser is an
example of a Web application.
In the preceding figure, a client sends a request for a resource, such as a Web page or a video, on the Internet.
The Web server interprets the client request and determines the type of resource requested by the client. If the
required resource is found, the Web server sends the resource to the client. Otherwise, an error message is sent to
the client.
All applications can be broken into three layers. Each layer has its own components and functionality. The
following figure depicts the various layers that constitute a Web application.
Presentation layer: Consists of the interface through which the users interact with the application.
Business logic layer: Consists of the components of the application that control the flow of execution
and communication between the presentation layer and the data layer.
Data layer: Consists of components that expose the application data stored in databases to the business
logic layer.
The architecture of a Web application is the manner in which layers are distributed and the way in which they
communicate with each other. Most applications are built by using all the three layers.
Single-tier architecture
Two-tier architecture
Three-tier architecture
N-tier architecture
Single-tier Architecture
In an application based on single-tier architecture, all the three layers are integrated together and can be installed
on a single computer. If the application needs to be accessed on multiple computers, a separate installation is
required on each computer. For example, Adobe Photoshop that is used to create and edit graphics is a standalone
application based on the single-tier architecture. The following figure displays the single-tier architecture.
Two-tier Architecture
In an application based on two-tier architecture, the three layers are distributed over two tiers, a client and a
server. The presentation layer resides on each client computer, the business logic layer resides either on the client
or on the server, and the data access layer resides on the server.
Depending on the business requirements, an organization can have the following types of two-tier application
architecture:
Fat client and thin server: The architecture in which the business logic layer resides on the client is
known as the fat client and thin server architecture. In this architecture, the client accepts user requests
and processes these requests on its own. The client communicates with the server only when the data for
communication or archival needs to be sent to the server.
Fat server and thin client: The architecture in which the business logic layer resides on the server is
known as the fat server and thin client architecture. In this architecture, the client accepts requests from
the users and forwards the same to the server. Further, the server processes these requests and provides
responses.
The two-tier architecture can be used when multiple users need to access and manipulate common data storage.
For example, an application needs to be developed to store an organization’s employee details in a database. In
addition, the application should allow the retrieval of employee details from the database. In this case, the
employee details need to be entered and retrieved by using multiple computers. Therefore, installing a database,
along with the application on each computer, may lead to storage of duplicate records. In addition, a user cannot
retrieve the employee details stored on some other computer. To avoid these problems, the application can be
installed on each computer. However, the database is installed on a single computer, and the same can be
accessed by the applications on multiple computers.
In the preceding example, the presentation and business logic layers are integrated and installed on each
computer. The applications installed on the computers send requests to the server (database) for the storage and
retrieval of data. On the other hand, the server accepts the requests and responds accordingly. In this setup, the
fat client and thin server architecture is used. The following figure displays the fat client and thin server
architecture.
In the preceding setup, the server only processes the data processing requests sent by the clients. Therefore, data
retrieval is fast. As the business logic resides on the client, the other applications installed on the clients respond
slowly. Further, if the business logic needs to be updated, the updates need to be installed on each client, which is
a time-consuming process.
To overcome these limitations, the business logic layer can be placed on the server along with the data layer. In
this way, only the presentation layer will be available on the clients. This, in turn, results in a faster response
from the other applications installed on the clients. In addition, if the business logic needs to be updated, the
updates need to be installed at only one location, which is on the server, rather than on each client. Such a setup
is an example of the thin client and fat server architecture.
The following figure displays the thin client and fat server architecture.
Three-tier Architecture
In an application based on three-tier architecture, the three layers of the application are placed separately as three
different entities. This architecture is used for those applications in which merging the business logic layer with
the presentation layer or the data layer may degrade the performance of the application. To improve the
application performance, the three layers are kept separately and the communication among the layers occurs
with the help of a request-response mechanism. The following figure displays the three-tier architecture.
The Three-tier Architecture
In the preceding figure, the business logic layer resides neither on a client nor on a database server. Instead, it
resides on a separate server, which is known as an application server.
N-tier Architecture
The three-tier architecture is implemented when an effectively-distributed client/server architecture, which
provides increased performance and scalability, is needed. However, it becomes a tedious task to design and
deploy applications based on the three-tier architecture. The separation of presentation, business logic, and
database access layers is not always obvious, because some business logic needs to appear on all the layers.
Therefore, there is a need to further divide these layers. This requirement has led to the expansion of the three-
tier application architecture to the N-tier application architecture.
A common approach to implement the N-tier architecture involves further separation of the presentation layer
and the data layer. For example, the presentation layer may be divided into the GUI layer and the presentation
logic layer. Similarly, the data layer may be divided into the data access layer and the data layer.
The N-tier architecture separates the various business processes into discrete units of functionality called
services. Each service implements a set of related business rules that defines what needs to be done and how it
needs to be done within an organization.
The N-tier application architecture provides improved flexibility and scalability of applications, as compared to
the three-tier application architecture. This is because the functioning of each layer is completely hidden from
other layers, which makes it possible to change or update one layer without recompiling or modifying the other
layers.
Introduction to Web Pages
A Web application consists of certain Web pages. A Web page is a Web document that can be accessed through
a Web browser. Web pages can be of the following types:
Static Web page: A Web page that contains only static content and is delivered to the user as it is
stored is called a static Web page. A static page does not offer any interactivity to the user.
Dynamic Web page: A Web page whose content is generated dynamically by a Web application or
that responds to user input and provides interactivity is called a dynamic Web page.
To create a dynamic and interactive Web page, you need to use scripting, which includes:
Client-side scripting
Server-side scripting
Client-side Scripting
Client-side scripting enables you to develop Web pages that can dynamically respond to user input without
having to interact with a Web server. Suppose you have a Web application that requires users to enter the user
name and password before displaying the home page. To check whether the user name and password provided by
the user are correct, the details need to be submitted to the server. However, before submitting the details to the
server, you need to ensure that the user does not leave the user name and password fields blank. To check
whether the user has left the user name and password fields blank, you can write a client-side script.
In addition to providing dynamic content, a client-side script helps in reducing the network traffic because it does
not need to interact with a Web server to provide a dynamic response to the user input. Client-side scripting also
speeds up the response time of a Web application. This happens because the processing happens at the client side
and round-trips to the server are not required. Scripting languages, such as VBScript and JavaScript, are used to
write client-side scripts.
Server-side Scripting
With the growing usage of the Internet as a medium of information, organizations are increasingly creating
dynamic Web applications. Server-side scripting helps in making a Web application dynamic by enabling the
application to access server-side resources, such as files and databases.
Server-side scripting provides users dynamic content that is based on the information stored at a remote location,
such as a back-end database. Server-side scripting includes code written in server-side scripting technologies,
such as Active Server Pages (ASP) and Java Server Pages (JSP).
A server-side script is executed on the Web server. When a browser requests for information on a website that is
created by using the server-side technology, the Web server, to which the request is sent, processes the script,
and then sends the results back to the browser. For example, if a Web page includes a server-side script to
display the current time of the system on which the website is hosted, the script will be processed at the server
and the current system time will be sent back to the browser.
Exploring ASP.NET
ASP.NET is a server-side technology that enables programmers to create dynamic Web applications. It has a
number of advanced features, such as simplicity, security, and scalability, which help you in developing robust
Web applications. These advanced features of ASP.NET are based on .NET Framework.
Introducing Microsoft’s Web Development Platforms
ASP.NET is built on Microsoft .NET Framework. The following figure depicts ASP.NET in the .NET
Framework.
As displayed in the preceding figure, ASP.NET is a Web application development framework built on top of
Microsoft’s .NET Framework, which provides various components, such as CLR and the base class library, to
develop robust applications. Common Language Runtime (CLR) is the runtime environment provided by .NET
framework, which manages code at runtime and provides core services, such as multiple language support and
strong type checking. The base class library is an object-oriented class library that provides a set of classes,
which enables you to perform a wide range of common programming tasks. These tasks include database
connectivity, file access, and string management. In addition to these common programming tasks, the base class
includes the classes that support specialized functions, such as developing console, GUI, and Web applications.
ASP.NET works on top of the .NET Framework and allows you to access the classes in .NET Framework.
ASP.NET interacts with the .NET Framework base classes, which, in turn, interact with CLR. CLR helps you to
code your ASP.NET applications in any language compatible with it including Microsoft Visual Basic and C#.
This provides a robust Web-based development environment.
Web forms
Model-View-Controller (MVC)
Web pages
Each model creates and structures a Web application by using different approaches. You can choose any of these
models depending on the requirement of the Web application to be developed.
Web Forms
The ASP.NET Web forms model enables you to develop dynamic and powerful websites. It provides many
controls, such as text boxes and check boxes, which help you to build an attractive user interface with data
access. It enables you to drag and drop server controls to design your Web forms pages. You can easily set the
properties, methods, and events for a control or a page to specify the page's behavior. Web forms are pages that
are written by using a combination of HTML, server controls, and server code, and users request them through
their browsers. It separates the HTML code from the application logic. To write server code for developing the
logic for the page, you can use a .NET language, such as Visual Basic or C#.
Using Web forms does not require you to have a hardcore developer background. You just need to be familiar
with the user interface controls and event handling. Moreover, Web forms allow a developer to use CSS,
generate semantically correct markup, and handle the development environment created for HTML elements
easily. This is because the developers just need to drag and drop the server controls and set their properties for
designing the page. The markup of these controls is generated automatically.
Model-View-Controller (MVC)
The MVC model is an alternative to the ASP.NET Web forms model for developing Web applications. It is a
light-weight model and supports existing ASP.NET features. It separates the following three main components
from an application:
Model: Refers to a set of classes that describes the data that the application works with. In addition,
these classes define the business logic that governs how the data can be manipulated.
View: Refers to the components that define an application's user interface. For example, the login form
that contains text boxes and buttons.
Controller: Refers to a set of classes that handle communication from the user and the overall
application flow. A controller responds to user input, communicates with the model, and decides the
view to render.
By separating the model, view, and controller within an application, the MVC model ensures loose coupling.
Therefore, it enables you to focus on one aspect of the implementation at a time. For example, you can
concentrate on designing a view without worrying about the business logic.
Loose coupling refers to an approach of interconnecting the components in such a way that
components depend on each other to the least extent.
The MVC model makes it easier to manage complexity by dividing an application into the model, the view, and
the controller. Therefore, it should be used for developing Web applications that are managed by large teams of
developers and Web designers.
Web Pages
Web pages are the simplest way to develop dynamic ASP.NET Web applications. The Web pages combine
HTML, CSS, JavaScript, and server code at one place to build dynamic websites. The Web pages framework
uses inline scripts rather than separate controller classes.
Web applications usually need to retrieve data from a database and display it to the user. In addition, Web
applications may also need to update the data in the database if the user changes the data using the User Interface
(UI). Since the key flow of information is between the database and the user interface, you might want to bind
these two pieces together. However, the user interface tends to change much more frequently than the database.
If the interface and the database logic are combined in a single object, then you need to modify the database logic
whenever the user interface is changed. This can result in errors, and therefore, requires the retesting of the entire
application.
The MVC development platform overcomes this limitation. It separates the application data, the presentation, and
the flow of application, into three separate components: the model, the view, and the controller. The model
manages the application data. It encapsulates data stored in a database as well as code used to manipulate the
data and enforces domain-specific business logic. The view manages the display of information. The controller
manages the flow of application, handles user input, and provides data to the relevant view. This separation of
view, model, and controller within an application allows you to change one component without affecting the
other component.
When an HTTP request is sent to the server by using a URL, the controller action associated with the URL is
executed in order to perform the required operation on a model. Then, a view is rendered and displayed to the
client. The following figure displays the interactions between the controller, the model, and the view.
The Interactons between the Controller, the Model, and the View
In the preceding figure, the HTTP request is sent to the controller. The controller works with the model, selects
the view, and finally, prepares the response. This response is rendered by the selected view and is sent to the
client.
Limiting interconnections between these components helps in isolating problems, which provides the following
benefits:
Separation of concerns: Loose coupling ensures dividing various application concerns into different
and independent software components. This allows developers to work on one component
independently at a time.
Simplified testing and maintenance: You can test each component separately to ensure that it is
working according to the requirements. This simplifies testing, maintenance, and troubleshooting
procedures.
Extensibility: The MVC model consists of a series of independent components. These components can
be easily replaced or customized depending upon the requirements, without hampering the functionality
of the application.
Structure of an ASP.NET MVC Project
When you create an ASP.NET MVC Web application project, separate folders are created for the MVC
components, such as model, view, and controller. Some of the project folders that are created by default are listed
in the following table.
In addition to the folders listed in the preceding table, an MVC application can include different types of files.
The following table lists some of the important file types with their descriptions.
Ends with .cshtml These files contain the user interface code.
Global.asax This is the global application file. You can use this
file to define global variables (variables that can be
accessed from any Web page in the Web
application). It is usually used for defining the
overall application events.
ASP.NET uses a hierarchy of configuration files to keep application configuration settings separate from the
application code. A configuration file is an XML file that contains configuration settings for an application and
has a .config extension.
Provides control and flexibility over the way you run applications.
Eliminates the need to recompile the application every time a setting changes.
Controls access to the protected resources and the location of remote applications and objects by
defining configuration settings.
The two files included in the hierarchy of configuration files are Machine.config and Web.config. The
Machine.config file always resides at the root of the configuration hierarchy and contains the global and default
settings for all the .NET Framework applications on the server. The Web.config file can reside at multiple levels
in the hierarchy. In case two versions of the same configuration setting exist at different hierarchal levels, the
local settings will take precedence over global settings.
The following table lists the configuration files, their hierarchy levels, and description.
Level File Name Description
Summary
In this chapter, you learned that:
Web applications are programs that are executed on a Web server and accessed from a Web browser.
An application can have one of the following types of architectures:
Single-tier architecture
Two-tier architecture
Three-tier architecture
N-tier architecture
A Web page is a Web document that can be accessed through a Web browser.
To create a dynamic and interactive Web page, you need to use scripting, which includes:
Client-side scripting
Server-side scripting
ASP.NET is a server-side technology that enables programmers to create dynamic Web applications.
ASP.NET offers various Web application development models. These are:
Web forms
Model-View-Controller (MVC)
Web pages
Controllers are C# classes that contain methods. Each public method in a controller is known as an
action method or a controller action.
Some of the features of ASP.NET MVC are:
Routing
Scaffolding
Convention-over-Configuration
Bundling and Minification
ASP.NET uses a hierarchy of configuration files to keep application configuration settings separate
from the application code.
A configuration file is an XML file that contains configuration settings for an application and has a
.config extension.
Chapter 2
Working with Controllers and Views
The purpose of many Web applications is to retrieve data from a database and display the same to the user. Web
applications may also need to update the data in the database if the user makes any change in the data using the
User Interface (UI). Since the flow of information takes place between the database and the user interface, you
might want to bind these two pieces together. However, because the user interface tends to change much more
frequently than the database, the approach of binding is not feasible.
The MVC pattern solves this problem by separating the application data, the presentation, and the flow of
application, into three separate components: the model, the view, and the controller. This separation allows you to
individually manage each component without affecting the functionality of other components.
This chapter discusses how to work with controllers and views. Further, it discusses how to route requests to
controller actions.
Objectives
Controllers within an MVC application are responsible for processing incoming user requests, executing the
appropriate application code, communicating with the model, and rendering the required view. In other words,
controllers manage the flow of the application.
Controllers are implemented in an MVC application as C# classes inherited from .NET Framework’s built-in
System.Web.Mvc.Controller class. A controller class contains an application logic in the form of various
public methods called action methods.
Creating a Controller
In ASP.NET MVC, controllers handle all the incoming requests. By convention, controllers are placed in a folder
named Controllers under the Web application folder. Thus, for creating a controller, you need to create a .cs file
containing the controller class in the Controllers folder. You create a controller class by inheriting the
Controller class, as shown in the following code snippet:
According to the ASP.NET MVC convention, the name of a controller is always suffixed by the word,
Controller. For example, the name of the Home controller will be the HomeController.
An application needs to handle user interactions, such as entering a URL in the Web browser, clicking a
hyperlink, and submitting a Web form. Each of these interactions sends a request to the Web server. In ASP.NET
MVC, such requests are handled by public methods in the controllers. These public methods are called action
methods or controller actions. You can define these action methods in a controller class. For example, the
following code snippet defines two action methods, Index and About , in the HomeController class:
Most action methods return an instance of a class that is derived from the ActionResult class. However, you can
also use specific return types, such as a string, int , or bool , as shown in the following code snippet:
In the preceding URL http://localhost:62053/home/index, 62503 is a port number. The port number is
automatically generated and may vary from project to project.
The following figure shows the response of the Index() action method in a browser.
A detailed example of a controller action that returns a value of the type, ActionResult, will be
discussed in the next section.
You can define a number of action methods in a controller. To invoke an action method, you can specify a URL
in the Web browser that contains the information about a controller and the action method within the controller.
For example, to invoke the Registration action method in the HomeController controller of a shopping
application, www.newbay.com, you need to specify the following URL in the Web browser:
http://newbay.com/Home/Registration
When the preceding URL is sent as a request to an MVC application through a Web browser, the MVC
application first searches for the HomeController class, and then searches for the Registration() action method
in it. If the Registration() action method is found, the MVC application executes the method, and then returns
the response back to the browser.
While requesting for a Web page, you may want to specify information other than the name of the Web page.
For example, while requesting for the product details, you may want to specify the category of the product. This
additional information can be sent to the server in the form of a query string included in the URL. For example,
consider the following URL:
http://www.demo.com/home/browse?Category=Soap
A query string is a part of a URL. It is used to pass data to Web servers. The query string is always
starts with a ? character followed by the data to be passed. The data is passed in the following format in
query string:
ParameterName=Value
Where:
In the preceding URL, a query string is defined that sets the value, Soap , for the Category parameter. The query
string passes this information to the browse() action method.
The browse() action method can access the value for the Category parameter by using its arguments. For
example, consider the following code snippet:
To access the value of a query string parameter in an action method, the parameter name of the action
method must be the same as the name of the query string parameter.
In the preceding code snippet, an action method named browse() is defined, which accepts a string argument
named Category . This argument provides the browse() action method access to the category value passed
through the query string. Once invoked, the action method, browse() , will display the following output:
http://localhost:62053/home/browse/5
In the preceding URL, a numeric parameter, 5, with the default name, id, is included in the URL. However, the
parameter is directly embedded within the URL, and not as a query string.
You can access the value of the ID parameter within the browse() action method by using the following code
snippet:
Once the action method is invoked through a URL, the browser renders the view and displays the following
output:
ID is: 5
A view is a combination of HTML markup and code that runs on the Web server. The code is embedded in the
Web pages using the Razor syntax. A Web application contains multiple views, where each view is responsible
for either displaying some information to users or taking inputs from a user.
The following figure represents a view displaying some information to the users.
The following figure represents a view that takes the input from a user.
A View that Takes Input from a User
You have already seen that user requests are processed by the action methods defined within the controllers.
Once a request is processed, a controller renders an appropriate view that is shown to the user. For this, an action
method needs to return a view. Consider the following code snippet:
You can also render a view defined in a different folder other than the default folder created by MVC for every
controller. To render a view named Index defined in the /Views/Special folder, you need to specify its full path,
as shown in the following code snippet:
In the preceding code snippet, the tilde (~) sign has been used to refer to the root application folder.
While using the tilde symbol, you must give the file extension of the view because this method bypasses
MVC’s default convention of finding a view.
In most cases, a view returns an instance of the ViewResult class, which, in turn, is derived from the
ActionResult class.
ViewData
ViewBag
ViewData
ViewData is a dictionary of objects derived from the System.Web.Mvc.ViewDataDictionary class. It enables
you to pass the data between a controller and a view. Here, values can be set using key/value pairs in the
controller action method, as shown in the following code snippet:
<p>
The message is: @ViewData[“Message”]
The Date and Time is: @ViewData[“ServerTime”]
</p>
ViewBag
ViewBag is a dynamic object that allows passing data between a controller and a view. You can add properties of
multiple types and their values by using the ViewBag object in a controller action method. Further, in the view,
you can use the ViewBag object to access the value added in the action method. You can add properties in a
ViewBag object using a very simple syntax, as shown in the following code snippet:
<p>
The message is: @ViewBag.Message
The Date and Time is: @ViewBag.ServerTime
</p>
The preceding code snippet will retrieve the message and the current date and time from the ViewBag object
method and render them in the view. ViewBag is just a dynamic wrapper over the ViewData dictionary. It means
that a value saved in the controller action by using ViewBag can also be accessed by using ViewData in a view.
For example, the Message property set by using ViewBag in the action method can be accessed by using ViewBag
and ViewData in the following ways in a view:
@ViewBag.Message
@ViewData[“Message”]
One of the most common differences between ViewBag and ViewData is that ViewBag works only in those cases
where the key being accessed is a valid C# identifier. For example, if you have used ViewData[“Customer
name”] and set its value, then you cannot access this value by using ViewBag . This is because a key with space is
not a valid C# identifier and the code will not run.
To render a view inside a browser, MVC uses Razor as the default view engine. The Razor view engine uses a
specific syntax to manage rendering of Web pages. Razor is a clean, lightweight, and simple view engine with a
minimum amount of syntax and code. Razor allows embedding server-side code in a view.
Apart from the Razor view engine MVC 4 also supports the ASPX view engine. Prior to MVC 3, ASPX
was the only supported view engine. Razor was introduced with MVC 3 and is the default view engine moving
forward.
Defining Razor
Razor is a markup syntax that allows you to embed server-side code (written in C# or VB) in an HTML markup.
A file containing server-side code in the C# syntax has an extension of .cshtml. However, a file containing
server-side code in VB has an extension of .vbhtml.
You have seen some of the basic Razor syntax rules. Now, let us discuss the syntax of various constructs in
Razor.
:
@{
//Server-side codes
----------------------
}
Razor loops are useful for displaying a list of items in a collection. For example, consider the following code
snippet:
In addition, you can use conditional constructs for making decisions on the basis of some condition. For example,
consider the following code snippet:
@if (@ViewBag.Product!=null) {
<text>Product is in stock.</text>
}
In the preceding code snippet, the @if construct is defined, which displays the text, Product is in stock , if
the condition, @ViewBag.Product!=null, is satisfied.
Including Comments
You can declare a Razor comment within the @* and *@ delimiters, as shown in the following code example:
Consider a scenario where you want to include some common markup in a number of views. One option is to
include the common markup in each view. However, this is a time-consuming task as you have to write the
markup on every view. In addition, if you need to make a change in the markup, the same change needs to be
applied on all the views that contain the markup. To overcome this problem, you can create a partial view and
invoke it wherever required. A partial view is a part of a view that can be used on multiple pages. Partial views
are created in the /Views/Shared folder. By convention, the name of a partial view is prefixed with an underscore
( _ ) character.
You can render a partial view in a view by using the @Html.Partial() method. MVC inserts the partial view,
HTML, into the parent view, and then returns the complete Web page to the browser. For example, the following
code snippet renders a partial view named _partialsummary within a view:
<div>@Html.Partial(“_partialsummary”)</div>
In the preceding code snippet, a partial view named _partialsummary is rendered within a <div> tag.
http://www.demo.com/product/products.aspx?category=laptop&manufacturer=dell&id=1243&color=black
Observe the preceding URL and you can understand that the website has a directory structure that contains a
product folder and a products.aspx file within that folder. This requires a direct relation between the URL and
the physical files stored on the disk. After receiving this URL request, the Web server directs the request to the
products.aspx file, which contains the code and markup to render a response to the browser. The products.aspx
file uses the data in the query string to identify the type of content to display.
In the preceding example, there is a one-to-one mapping between the URLs and the file system. However, this is
usually not the case in an MVC application. In an MVC application, whenever a user request is generated, the
URL of the incoming request is routed to a controller action. The mechanism for locating an appropriate action
method for a given URL is called routing. Routing in the ASP.NET MVC framework serves the following two
main purposes:
In an ASP.NET MVC application, because the URLs do not need to map with files, the URLs can be more
descriptive of the user’s action, and do not need to use long and complicated query strings.
http://www.demo.com/product/products/laptop/dell/1243/black
The preceding URL points to the products() action method of the product controller. The routing mechanism
passes the values, laptop, dell, 1243, and black, to the action method that the URL points to. The action method
can use these values to determine the content to be displayed.
A user can easily modify the preceding URL to navigate to another page of the site. In addition, one important
benefit of this kind of URL is Search Engine Optimization (SEO). SEO is the process of optimizing a URL for a
search engine to improve the page ranking in search engine results. SEO reflects what people search for by using
the keywords typed into search engine and how search engines work to process these requests. Search engines
mainly work using URLs. Specifying a meaningful and more comprehensive URL is critical to make the
application more search engine-friendly.
An ASP.NET MVC application defines the default route for mapping URLs in a given pattern with specific
controller actions. However, you can define additional routes if there is a need to provide custom routes.
Every MVC application needs at least one route to define how the application should handle user requests.
Whenever you create an ASP.NET MVC application, the application, by default, generates a route for routing
user requests. The Global.asax file has a method, Application_Start() , defined in it. This is the first method
that is invoked when an MVC application starts. Finally, this method invokes the RegisterRoutes() static
method, which is defined in the RouteConfig.cs file in the App_Start folder. The RegisterRoute() method has
the definition of the default route, as shown in the following code snippet:
routes.MapRoute(
name: “Default”,
url: “{controller}/{action}/{id}”,
defaults: new { controller = “Home", action = “Index”, id = UrlParameter.Optional }
);
The preceding code snippet defines a route named Default. This route defines a URL pattern,
{controller}/{action}/{id}, with three segments: controller , action, and id . In addition, it defines the
default value for each segment in the pattern. The default value of the controller segment is defined as Home ,
the action segment is Index , and id is an optional parameter. Therefore, if a URL does not specify an action
method, the request is routed to the default action method, Index(), in the specified controller. Similarly, if a
URL request does not specify a controller, the request is routed to the Index() action method of the Home
controller.
The following table shows the requested URLs and the controllers, actions, and ID parameters that they map
with, as per the default routing scheme:
The URL Mapping with Controller Actions as per the Default Routing Scheme
Routing Patterns
The default route defines the routing mechanism for URLs of the form,
http://<domain>/<contoller>/<action>/<id>. However, to handle URLs that use a different form, additional
routes need to be defined. To define a new route, a URL pattern needs to be created. This URL pattern defines a
route pattern that a route will match with. A route pattern can contain variable placeholders or literal values or a
combination of these two. These placeholders and literals are placed in segments of the URL separated by the
slash ( / ) character. Placeholders are enclosed in braces, { and }.
For example, consider the following URL pattern and the matching URL:
In the preceding URL, the three placeholders, {controller}, {action} , and {id} , have the values, employee ,
details , and 2, respectively. You can also define multiple placeholders in a segment. However, these
placeholders must be separated by literal values. For example, consider the following URL:
http://www.demo.com/dell-US/show
In the preceding URL, the {company}-{country}/{action} pattern is used. You can see that in the first
segment, two placeholders {company} and {country} are created, separated by a dash (-) literal.
A route pattern can also have a combination of literal values and variable placeholders, as shown in the following
route pattern:
blog/{action}/{entry}
In the preceding route pattern, the first segment has a literal value, blog, and the second and third segments
define variable placeholders.
http://www.demo.com/blog/show/321
In the preceding URL, the blog / {action} / {entry} pattern is used. Here, blog represents a literal value. The
value, show , is specified for the placeholder, action, and the value, 321 , is specified for the placeholder, entry .
The preceding URL is routed to the show() action method of the blog controller, and the value 321 is passed to
the show() action method as a parameter.
Ordering Routes
For large applications, you may need to register multiple routes. However, when you define multiple routes, you
should define them in a specific order. This is because whenever a URL request is received by the application,
the route matching is done from the first route to the last route. While matching the routes, whenever a match is
encountered, no more routes are tried after that. This behavior can cause unexpected problems.
routes.MapRoute(
name: “general”,
url: “{controller}/{action}”,
defaults: new { controller = “Home”, action = "Index”}
);
routes.MapRoute(
name: “admin”,
url: “Admin/{action}”,
defaults: new { controller = “Admin”, action = “Create”}
);
The first route contains two placeholder segments and sets the default value of the controller parameter to Home
and the action parameter to Index . On the other hand, the second route contains a constant segment, Admin , and a
variable placeholder segment, and sets the default value of the controller parameter to Admin and the action
parameter to Create. It causes problems in routing. This is because the first route can match just about any value
entered for a controller and action segment. This would even include the value, Admin for the controller segment.
It means that when you call a URL by using the value, Admin , for the first segment, the first route will be called
and the second route will never be called.
To fix this problem, you need to switch the order of the routes so that the second route named admin is defined
before the first route named general.
While creating routes, you may need to place extra constraints to ensure that the route matches only with the
appropriate requests. Providing constraints along with the route pattern gives a better control over how and when
a route matches an incoming request URL. For example, if you want a URL in the form toys/45 to specify a toy
with the id 45, you create a route pattern like toys/{id} . However, this route pattern can also match with the
URL toys/create. For id, you must constraint the URL to match only with the segments comprising digits. This
is where constraints are useful along with the route pattern. Constraints allow you to apply a regular expression to
a route segment to ensure that only appropriate request will match. For example, consider the following route:
routes.MapRoute(
name: "general",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id=UrlParameter.Optional},
constraints: new { id = @"\d*" }
);
The preceding route has three segments: controller , action, and id. In addition, the default value for the
controller segment is set to Home , the action segment is set to Index , and id is an optional parameter. In the
preceding route, a constraint is applied on the id segment, which specifies that the id parameter can match only
with an integer value. The following table gives an example of URLs that may or may not match the preceding
route.
URL Match?
http://www.demo.com/product/toy/2341 Yes
http://www.demo.com/product/toy/car No
http://www.demo.com/product/toy Yes
http://www.demo.com/product/ Yes
http://www.demo.com/ Yes
Ignoring a Route
In contrast to defining routes that map with controllers and actions, you can prevent URLs from being evaluated
against routes. For this, you can use the IgnoreRoute() method that adds a special route and tells the routing
engine to ignore requests for any URL that matches the given pattern.
routes.IgnoreRoute(“{resource}.axd/{*pathInfo}”);
The preceding code snippet ignores any request for files with the extension, .axd. This file extension is used for
common ASP.NET handlers, such as Trace.axd and WebResource.axd. With the preceding call to the
IgnoreRoute() method, the requests for .axd files are handled as normal requests to ASP.NET and are not
handled by the routing engine.
Summary
In this session, you learned that:
Controllers are implemented in an MVC application as C# classes inherited from .NET Framework’s
built-in Controller class.
A controller class contains an application logic in the form of various public methods called action
methods.
The controllers are placed in a folder named Controllers under the Web application folder.
To invoke an action method, you can specify a URL in the Web browser that contains the information
about a controller and the action method within the controller.
A view is a combination of HTML markup and code that runs on the Web server.
The following two common techniques are used to pass data from a controller to a view:
ViewData
ViewBag
ViewData is a dictionary of objects derived from the ViewDataDictionary class.
ViewBag is just a dynamic wrapper over the ViewData dictionary.
Razor is a markup syntax that allows you to embed server-side code (written in C# or VB) in an HTML
markup.
The Razor view engine is responsible for interpreting the server-side code embedded inside a view file.
A partial view is a part of a view that can be used on multiple pages.
You can render a partial view in a view by using the @Html.Partial() method.
The mechanism for locating an appropriate action method for a given URL is called routing.
SEO is the process of optimizing a URL for a search engine to improve the page ranking in search
engine results.
An ASP.NET MVC application defines the default route for mapping URLs in a given pattern with
specific controller actions.
Every MVC application needs at least one route to define how the application should handle user
requests.
The default route defines the routing mechanism for URLs of the form,
http://<domain>/<contoller>/<action>.
A route pattern can contain variable placeholders or literal values or a combination of these two.
Providing constraints along with the route pattern gives a better control over how and when a route
matches an incoming request URL.
Chapter 3
Working with Models and Helper Methods
Most applications have some data associated with them. Therefore, interaction with the data becomes critical for
any application. In an MVC application, the component that enables interaction with data is called model. To
access and retrieve data in an application, you need to know how to work with models.
A user interacts with an application with the help of views. Therefore, it is important to design effective views.
ASP.NET MVC provides a number of helper methods that help you create views easily and provide several
additional benefits.
This chapter discusses how to work with models and helper methods in an ASP.NET MVC application.
Objectives
The software development team has already created the Home, About Us, and Contact Us pages of the
application. Now, they need to manage the data related to the products. In an MVC application, this is the model
that manages all the tasks related to handling data. The model represents the data and the business logic of an
application.
A model consists of a set of classes, where the objects of the classes represent the data associated with the
application. Suppose you have the data of products, which includes product name, description, and price. To
represent this data, you need to create a model class named Product with properties, such as Id, name ,
description, and price . The structure of this class should be similar to the structure of the Product table in the
database in such a way that there is a direct mapping between the properties of the Product class and the fields
of the Product table. This is called object-relational mapping (ORM). The following figure shows a direct
mapping between the properties of the Product class and the fields of the Product table.
The Object-Relational Mapping
A model also represents the business logic of an application. For example, in case of the Newbay website, the
developer has implemented the functionality that allows the administrator to compute the total monthly sales
generated online. In this case, the model is responsible for performing the calculation.
Once defined, you can access a model within a controller. Moreover, you can also pass model data from a
controller to a view. This view can be created manually or automatically. The ASP.NET MVC framework
provides a feature called scaffolding, using which you can create auto-generated controllers and views.
Creating a Model
Consider the scenario of Newbay where the application needs to maintain information about the products, such as
Id, product name, description, and price. For this, the team needs to add a class in the model that defines the
required properties of the product.
Consider the scenario of the Newbay application, where a user requests for some information related to a product
through the following URL:
www.Newbay.com/Home/Product
Once received, the server sends the request to the Product action method of the Home controller. The Product
action method coordinates with the model to access the data and displays it through a view.
To access the model from the Product action method, you need to create an object of the model class in the
Product action method, as shown in the following code snippet:
using Newbay.Models
Here, Newbay.Models is the namespace that contains the Product model class, and Newbay is the name of your
application.
Passing Model Data from a Controller to a View
You have seen how to access a model within a controller. However, to be displayed to a user, the model data
needs to be made accessible to a view. For this, the controller can pass the model data to the view at the time of
invoking the view. The model data passed could be a single object or a collection of objects.
You can pass the model data from a controller to a view by using ViewBag. To pass the data, you need to add the
highlighted portion of the following code snippet in the Product action method of the Home controller:
@ViewBag.product.name<br/>
@ViewBag.product.description<br/>
@ViewBag.product.price<br/>
In the preceding code snippet, the razor syntax is used to display the property values of the object passed through
ViewBag .
You can also use the following code snippet as an alternative to the previous code snippet:
@{
var product = ViewBag.product;
}
@product.name <br/>
@product.description <br/>
@product.price <br/>
In the preceding code snippet, a reference of the object passed through ViewBag is stored in a variable, product.
The properties of the product are then displayed using this object.
As an alternative to using ViewBag, you can pass the data to a view by passing the object as a parameter to the
view, as shown in the highlighted portion of the following code snippet:
@Model.name <br/>
@Model.description <br/>
@Model.price <br/>
Alternatively, you can also use the following code snippet to access the passed information in the view:
@{
var product = Model;
}
@product.name <br/>
@product.description <br/>
@product.price <br/>
To access the data stored in ViewBag from within the view, you need to add the following code snippet in the
view:
@{
var products = ViewBag.products;
}
@foreach (var p in products)
{
@p.name<br/>
@p.description<br/>
@p.price<br/>
<br/>
}
As an alternative to using ViewBag, you can pass the data to a view by passing a collection of objects as a
parameter to the view, as shown in the following code snippet:
@{
var products = Model;
}
@foreach(var p in products)
{
@p.name <br/>
@p.description <br/>
@p.price <br/>
<br/>
}
You have seen how to pass model data from a controller to a view. However, when the data is passed in this
manner, the view is not aware of the exact type of the data being passed. As a result, you do not get the benefit of
intellisense while trying to access the properties of the passed object. In addition, you do not get the benefits of
strong typing and compile-time checking of code, such as correctly typed property and method names.
To secure the preceding benefits, you can typecast the model data to a specific type, as shown in the following
code snippet:
@{
var product = Model as Newbay.Models.Product;
}
@product.name <br/>
@product.description <br/>
@product.price<br/>
In the preceding code snippet, the Model object is cast to the type, Newbay.Models.Product. As a result of this
casting, the product object is created as an object of the type, Newbay.Models.Product, and enables compile-
time checking of code.
However, if you want to avoid explicit type casting of the model object, you can create a strongly typed view and
obtain the benefits of strong typing. A strongly typed view specifies the type of model it expects by using the
@model declaration, as shown in the following code snippet:
@model Newbay.Models.Product
Now, you can access the properties of the model object by using the following code snippet:
@Model.name <br/>
@Model.description <br/>
@Model.price <br/>
To avoid specifying a fully qualified type name for the model, you can use the @using declaration, as shown in
the following code snippet:
@using Newbay.Models
@model Product
A better approach for namespaces that can be used often within views is to declare the namespace in the
web.config file within the Views directory, as shown in the highlighted part of the following code snippet:
<namespaces>
@model IEnumerable<Newbay.Models.Product>
The preceding declaration specifies that the view can accept a collection of objects of the type, Product. Now,
you can access the collection of model objects in the view by using the following code snippet:
@{
@foreach(var p in products)
{
@p.name <br/>
@p.description <br/>
@p.price <br/>
<br/>
}
Introduction to Scaffolding
So far you have manually created the controllers and views to handle the information related to a product and
display the same to the user. This requires a lot of time and manual coding. To overcome this problem, ASP.NET
provides a feature called scaffolding that builds an application quickly.
Scaffolding allows you to create auto-generated controllers and their corresponding views after examining the
properties of the associated model. Scaffolding uses a predefined convention for naming controllers and views. In
addition, it knows where to place auto-generated codes for the application to work.
Scaffolding provides various templates for creating controllers and associated views. Some of these templates
are:
Empty MVC controller: The empty controller template adds a class derived from the Controller
class to the Controllers folder. This class has only one action method by the name, Index, with no code
inside it.
MVC controller with empty read/write actions: This template adds a controller class with action
methods, such as Index, Details, Create, Edit, and Delete. These action methods have some code written
inside them. However, they do not perform any useful function. You can make them functional by
adding your own code and creating the views for each action method.
API controller with empty read/write actions: This template adds a class derived from the
ApiController base class. You can use this template to build a Web API for your application.
MVC controller with read/write actions and views using Entity Framework: This template adds a
controller class with action methods, such as Index, Details, Create, Edit, and Delete. It also generates
all the required views and the code to retrieve information from a database.
List: This template generates the markup to display the list of model objects.
Create: This template generates the markup to add a new object to the list.
Edit: This template generates the markup to edit an existing model object.
Details: This template generates the markup to show the details of an existing model object.
Delete: This template generates the markup to delete an existing model object.
Scaffolding templates gives you the basic code required to implement the create, read, update, and
delete (CRUD) functionality in an application. However, you may need to customize the code/markup as per
your specific requirements. Using scaffolding is not necessary. However, it can speed up the development
process. If you do not like the scaffolding behavior, you can write the code/markup yourself from scratch.
The List template is used to create a view that displays a list of model objects. This list is passed to the view
through a controller action, as shown in the following code snippet:
{
var products = new List<Product>();
//Code to populate the products collection
return View(products);
}
When you create a view for the Product model created earlier using the List template, the following markup is
generated:
@model IEnumerable<Newbay.Models.Product>
@{
ViewBag.Title = "Index";
}
<table>
<tr>
<th>@Html.DisplayNameFor(model => model.name)</th>
<th>@Html.DisplayNameFor(model = > model.description)</th>
<th>@Html.DisplayNameFor(model => model.price)</th>
</tr>
@foreach (var item in Model) {
<tr>
<td>@Html.DisplayFor(modelItem => item.name)</td>
<td>@Html.DisplayFor(modelItem => item.description)</td>
<td>@Html.DisplayFor(modelItem => item.price)</td>
<td>
@Html.ActionLink("Edit", "Edit", new {id=item.ID}) |
@Html.ActionLink("Details", "Details", new {id=item.ID})|
@Html.ActionLink("Delete", "Delete", new {id=item.ID})
</td>
</tr>
}
</table>
In the preceding markup, the Html.DisplayNameFor() helper method is used to display the names of model
properties, and the Html.DisplayFor() helper method is used to display the values of the model properties. In
addition, the Html.Actionlink() helper method is used to create links to edit, delete, and view details for a
product. The @model IEnumerable<Newbay.Models.Product> method is used to type the view to a collection of
Product objects. @foreach (var item in Model) is used to iterate over the collection of products and display
the property values associated with each product individually. The Html.DisplayNameFor() and
Html.DisplayFor() helper methods use a parameter to specify the names and the values of the properties to be
displayed on the view.
You will learn more about helper methods in the next section.
The sample output generated by the preceding code snippet is displayed in the following figure.
The Create template can be used to generate a view that needs to be used for accepting the details of a new
object to be stored in a data store.
To render a view based on the Create template, you need to create an action method. Consider an action method
name Create() in the Home controller, as shown in the following code snippet:
{
return View();
}
The preceding code snippet will render a view named Create stored in the Views/Home folder within an MVC
project. The Create() action method is invoked when a user clicks the Create link on the view generated through
the List template.
When you create a view named Create for the Product model using the Create template, the following markup is
generated:
@model Newbay.Models.Product
@{
ViewBag.Title = "create";
}
<h2>create</h2>
@using (Html.BeginForm()) {
@Html.ValidationSummary(true)
<fieldset>
<legend>Product</legend>
<div class="editor-label">
@Html.LabelFor(model => model.name)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.name)
@Html.ValidationMessageFor(model => model.name)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.description)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.description)
@Html.ValidationMessageFor(model => model.description)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.price)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.price)
@Html.ValidationMessageFor(model => model.price)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
</div>
@Html.ActionLink("Back to List", "Index")
</div>
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}
In the preceding markup, the BeginForm helper method marks the start of a form. The
Html.ValidationSummary() validation helper is used to display the summary of all the error messages at one
place. Further, the Html.LabelFor() helper method renders an HTML label element with the name of the
property, and the Html.EditorFor() helper method displays a textbox to accept the value of a model property. In
addition, the Html.ValidationMessageFor() validation helper is used to display a validation error message for
the associated model property.
The preceding code snippet will generate the interface as shown in the following figure.
The View Generated by Using the Create Template
When the user fills data in the preceding form and clicks the Create button, an HTTP POST request is sent to the
Create() action method within the Home controller. The data filled by the user in the form is also sent along
with the request.
We already have an action method named Create in the Home controller. However, this action method is simply
designed to render the Create view. To handle the HTTP POST request, another action method named Create
needs to be created. This new action method needs to be differentiated from the previous Create() method by
decorating it with an HttpPost attribute, as shown in the following code snippet:
[HttpPost]
{
/*Code to save the details of the product object to a data store and return an appropriate
view. */
}
Similarly, the other action method can be decorated with an HttpGet attribute, as shown in the following code
snippet:
[HttpGet]
}
Whenever the Create action method is requested through a URL request, the method with the [HttpGet] attribute
is invoked. However, whenever the Create action method is invoked as a result of submitting the Create form, the
method with the [HttpPost] attribute is invoked.
The Edit Template
The Edit template can be used to generate a view that needs to be used for modifying the details of an existing
object stored in a data store.
To render a view based on the Edit template, you need to create an action method that passes the model object to
be edited to the view.
When you create a view named Edit for the Product model using the Edit template, the following markup is
generated:
@model Newbay.Models.Product
@{
ViewBag.Title = "Edit";
}
<h2>Edit</h2>
@using (Html.BeginForm()) {
@Html.ValidationSummary(true)
<fieldset>
<legend>Product</legend>
@Html.HiddenFor(model => model.ID)
<div class="editor-label">
@Html.LabelFor(model => model.name)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.name)
@Html.ValidationMessageFor(model => model.name)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.description)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.description)
@Html.ValidationMessageFor(model => model.description)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.price)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.price)
@Html.ValidationMessageFor(model => model.price)
</div>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
}
<div>
@Scripts.Render("~/bundles/jqueryval")
}
In the preceding markup, the Html.LabelFor() helper method renders an HTML label element with the name of
the property. Further, the Html.EditorFor() helper method is used to display a textbox to accept the value of a
model property. In addition, the Html.ValidationMessageFor() helper method is used to display a validation
error message.
The preceding code snippet will generate the interface as shown in the following figure.
The preceding Edit view is rendered by the Edit() action method in the Home controller. However, when the
user edits the data in the preceding form and clicks the Save button, an HTTP POST request is sent to the Edit()
action method. To handle the HTTP POST request, another action method named Edit() needs to be created
with an HttpPost attribute.
The Details Template
The Details template is used to create a view that displays details of a model object. The details of the model
object are passed to the view through a controller action.
When you create a view for the Product model using the Details template, the following markup is generated:
@model Newbay.Models.Product
@{
ViewBag.Title = "Details";
}
<h2>Details</h2>
<fieldset>
<legend>Product</legend>
<div class="display-label">
@Html.DisplayNameFor(model => model.name)
</div>
<div class="display-field">
@Html.DisplayFor(model => model.name)
</div>
<div class="display-label">
@Html.DisplayNameFor(model => model.description)
</div>
<div class="display-field">
@Html.DisplayFor(model => model.description)
</div>
<div class="display-label">
@Html.DisplayNameFor(model => model.price)
</div>
<div class="display-field">
@Html.DisplayFor(model => model.price)
</div>
</fieldset>
<p>
The preceding code snippet will generate the interface as shown in the following figure.
The Delete template can be used to generate a view that needs to be used for deleting an existing object from a
data store.
To render a view based on the Delete template, you need to create an action method that passes the model object
to be deleted to the view.
When you create a view for the Product model using the Delete template, the following markup is generated:
@model Newbay.Models.Product
@{
ViewBag.Title = "Delete";
}
<h2>Delete</h2>
<fieldset>
<legend>Product</legend>
<div class="display-label">
@Html.DisplayNameFor(model => model.name)
</div>
<div class="display-field">
@Html.DisplayFor(model => model.name)
</div>
<div class="display-label">
@Html.DisplayNameFor(model => model.description)
</div>
<div class="display-field">
@Html.DisplayFor(model => model.description)
</div>
<div class="display-label">
@Html.DisplayNameFor(model => model.price)
</div>
<div class="display-field">
@Html.DisplayFor(model => model.price)
</div>
</fieldset>
@using (Html.BeginForm()) {
<p>
<input type="submit" value="Delete" />
@Html.ActionLink("Back to List", "Index")
</p>
}
In the preceding markup, the Html.DisplayNameFor() helper method is used to display the names of model
properties. Further, the Html.DisplayFor() helper method is used to display the values of the model properties.
In addition, the Html.Actionlink() helper method is used to create a link to list the details for a product.
The preceding code snippet will generate the interface as shown in the following figure.
The preceding Delete view is rendered by the Delete() action method in the Home controller. However, when
the user clicks the Delete button, an HTTP POST request is sent to the Delete() action method. To handle the
HTTP POST request, another action method named DeleteConfirmed() needs to be created with an HttpPost
attribute.
Working with HTML and URL Helpers
Consider a scenario where the development team working on the Newbay shopping application needs to give an
option to the user to access the details of different products online. Moreover, the user should be able to navigate
the different Web pages easily. In order to create the views for these features, you can use the HTML markup.
Although developing views using HTML is quite simple, yet it often becomes difficult to handle specific issues
using HTML. Some of these issues are:
Ensuring that a URL within a link actually points to the correct location
Ensuring that form elements have proper names and are bound to the correct values to implement model
binding
To overcome these problems, ASP.NET MVC offers a standard set of helper methods. These helpers help you
work with HTML and URLs. The benefit of using these helpers is that they help you generate links and URLs
from the routing configuration. As a result, a change in routes is automatically reflected in the links and URLs.
Some of the helper methods that can be used in building an MVC application are:
Html.ActionLink()
Html.BeginForm() and Html.EndForm()
Html.Label() and Html.LabelFor()
Html.DisplayNameFor() and Html.DisplayFor()
Html.TextBox() and Html.TextBoxFor()
Html.TextArea() and Html.TextAreaFor()
Html.EditorFor()
Html.Password() and Html.PasswordFor()
Html.HiddenFor()
Html.CheckBox() and Html.CheckBoxFor()
Html.DropDownList() and Html.DropDownListFor()
Html.RadioButton() and Html.RadioButtonFor()
Url.Action()
Html.ActionLink()
The Html.ActionLink() method generates a hyperlink (anchor tag) that points to a controller’s action method.
The Html.ActionLink() helper uses the internal routing mechanism to generate the target URL for the hyperlink.
The Html.ActionLink() helper method has the following syntax:
In the preceding syntax, AnotherAction is the name of the action method that acts as the target for the hyperlink,
and Link Text is the text to be displayed as the link.
Assuming that the preceding hyperlink is contained in a view associated with the Home controller, the preceding
syntax will produce the following markup:
<a href="/Home/AnotherAction">LinkText</a>
However, if you want to navigate to an action method in a different controller, you can consider the following
syntax:
In the preceding syntax, AnotherAction is the name of the action method that acts as the target for the hyperlink,
Link Text is the text to be displayed as the link, and AnotherController is the name of the controller that
contains the action method, "AnotherAction" .
The Html.BeginForm() method marks the start of a form. This helper method coordinates with the routing engine
to generate a proper URL. The Html.BeginForm() helper method outputs the opening <form> tag. The
Html.BeginForm() helper method has the following syntax:
@{Html.BeginForm("MyAction","MyController");}
In the preceding syntax, MyController is the name of the controller and MyAction is the name of the action
method to which the form will be posted.
Once created, you need to close the <form> tag by rendering a closing </form> tag. The Html.EndForm() helper
method renders the closing </form> tag. The Html.EndForm() helper method provides a way to end the form
created by using the Html.BeginForm() helper method. The Html.EndForm() helper method has the following
syntax:
@{Html.EndForm();}
However, to avoid using the Html.EndForm() helper method to close the form, you can make use of the
following syntax:
@using (Html.BeginForm("MyAction","MyController"))
In the preceding syntax, an @using statement has been used with the Html.BeginForm() method. The preceding
syntax will produce the following markup:
<form action="Mycontroller/MyAction">
</form>
The advantage of using @using before the Html.BeginForm() method is that it automatically renders a closing
</form> tag and you do not need to explicitly include the Html.EndForm() method to add the closing </form>
tag.
The Html.Label() helper method is used to render an HTML <label> element, which refers to the specified
model property. The Html.Label() helper method has the following syntax:
@Html.Label("propertyname")
For example, with reference to the Product class, the name of the product can be displayed by using the
following statement.
@Html.Label("name")
<label for="name">name</label>
However, while writing the property name in the Label() method, there are chances that you may misspell the
name of the property. Such mistakes would not be detected at the time of compilation of the code. To overcome
such problems, you can use the Html.LabelFor() helper method.
The Html.LabelFor() helper method is the strongly typed version of the Html.Label() helper method. The
Html.LabelFor() helper method has the following syntax:
The Html.LabelFor() helper method uses a lambda expression as its parameter, which provides compile time
checking and ensures that the correct property name is specified.
In addition, it gives you the benefit of intellisense while trying to access the model properties, as shown in the
following figure.
This helps in avoiding the chance of misspelling the name of the property.
Similar to the Html.Label() helper method, the Html.LabelFor() helper method renders an HTML <label>
element with the name of the property.
For example, with reference to the Product class, the name of the product, the name property, can be displayed
by using the following statement:
The Html.DisplayNameFor() helper method is used to display the names of model properties. The
Html.DisplayNameFor() helper method has the following syntax:
In the preceding syntax, propertyname is the name of the property defined in the model class. For example, with
reference to the Product class, the name of the product can be displayed by using the following statement:
name
The Html.DisplayFor() helper method is used to display the values of the model properties. The
Html.DisplayFor() helper method has the following syntax:
@Html.DisplayFor(model => model.propertyname)
In the preceding syntax, propertyname is the name of the property defined in the model class. Assuming that the
preceding syntax is used for displaying the name of a product defined in the model class, the preceding syntax
would be written as the following statement:
The Html.TextBox() helper method renders an input tag with the type attribute set to text. The Html.TextBox()
helper method is used to accept free-form input from a user. The Html.TextBox() helper method has the
following syntax:
@Html.TextBox("propertyname", Model.propertyname)
In the preceding syntax, propertyname is the name of the property defined in the model class. The preceding
syntax will generate the following markup:
In the preceding markup, val is the value associated with the model property, propertyname.
The Html.TextBoxFor() helper method is the strongly typed version of the Html.TextBox() helper method. The
Html.TextBoxFor() helper method has the following syntax:
The preceding syntax generates the same markup as that of the Html.TextBox() helper method.
The Html.TextArea() helper method is used to render a <textarea> element for multi-line text entry. The
Html.TextArea() helper method enables you to specify the number of columns and rows to display in order to
control the size of the text area. The Html.TextArea() helper method has the following syntax:
In the preceding syntax, row and column specify the number of rows and columns. propertyname specifies the
name of the model property. The fifth parameter in the preceding syntax specifies additional HTML attributes for
the text area. In this case, it has been specified as null .
To include a text area with 5 rows and 20 columns for the description property of the Product model, you can
write the following statement:
Assuming that the description property of the Product model includes the value, Newly launched with the
touch screen, the preceding statement will generate the following markup:
<textarea cols="20" id="description" name="description" rows="5"> Newly launched with touch
screen</textarea>
The Html.TextAreaFor() helper method is the strongly typed version of the Html.TextArea() helper method.
It has the following syntax:
The Html.TextAreaFor() helper method generates the same markup as that of the Html.TextArea() helper
method.
Html.EditorFor()
The Html.EditorFor() helper method is used to display an editor for the specified model property. The
Html.EditorFor() helper method has the following syntax:
In the preceding syntax, propertyname is the name of the property defined in the model class. For example, to
edit the value associated with a name field, the preceding syntax can be written as the following statement.
The Html.Password() helper method renders a password field. The Html.Password() helper method has the
following syntax:
@Html.Password("UserPassword",Model.UserPassword)
The Html.PasswordFor() helper method is the strongly typed version of the Html.Password() helper method. It
is used to render a password field. The Html.PasswordFor() helper method has the following syntax:
@Html.Hidden("propertyname", Model.propertyname)
In the preceding markup, val is the value of the model property, propertyname.
The Html.HiddenFor() helper method is the strongly typed version of the Html.Hidden() helper method. The
Html.HiddenFor() helper method has the following syntax:
In the preceding syntax, propertyname is the name of the model property that needs to be added to a hidden
field.
The Html.CheckBox() helper method renders a check box input element that enables the user to select a true or
false condition. The Html.CheckBox() helper method has the following syntax:
@Html.CheckBox("propertyname")
In the preceding markup, the checkbox helper method renders a hidden input in addition to the checkbox input.
This is required because a browser submits a value for a checkbox only when the checkbox is selected. The
hidden input guarantees that a value will be submitted, even if the user does not select the checkbox.
The Html.CheckBoxFor() helper method is the strongly typed version of the Html.CheckBox() helper method.
The Html.CheckBoxFor() helper method has the following syntax:
The Html.DropDownList() helper method returns a <select/> element. The Html.DropDownList() helper
method allows selection of a single item. The <select/> element shows a list of possible options and also the
current value for a field. The Html.DropDownList() helper method has the following syntax:
In the preceding syntax, A, B, and C are the options available in the drop down list. Choose is the default value at
the top of the list, indicating to the user that a value needs to be chosen from the drop-down list.
Consider an example where you want to create a drop-down list named City with the values Paris, Tokyo, and
Rome populated in it. For this, you can use the following statement:
<option value="">Choose</option>
<option>Paris</option>
<option>Tokyo</option<
<option>Rome</option>
</select>
The Html.DropDownListFor() helper method is the strongly typed version of the Html.DropDownList() helper
method. The Html.DropDownListFor() helper method has the following syntax:
The Html.RadioButton() helper method is used to provide a range of possible options for a single value. For
example, if you want the user to select the gender, you can use two radio buttons to present the choices. The
Html.RadioButton() helper method has the following syntax:
In the preceding syntax, name is the name of the radio button input element, value is the value associated with a
particular radio button option, and isChecked is a Boolean value that indicates whether the radio button option is
selected or not.
For example, to accept the gender of a user, you can create a collection of two radio buttons, as shown in the
following code snippet.
Url.Action()
The Url.Action() helper method will return the URL for the specified action within a controller. The following
syntax can be used to build a URL from a given controller and action:
@Url.Action("ActionName", "ControllerName")
For example, to generate a URL of the Index action in the Home controller, the following statement can be used:
@Url.Action("Index", "Home")
The preceding statement will generate the following output:
/Home/Index
Summary
In this chapter, you learned that:
In an MVC application, the component that enables interaction with data is called model.
A model consists of a set of classes, where the objects of the classes represent the data associated with
the application.
The model data passed could be a single object or a collection of objects.
Scaffolding provides the following templates for creating controller and associated views:
Empty controller
Controller with empty read/write actions
API controller with empty read/write actions
Controller with read/write actions and views using Entity Framework
Scaffolding provides the following templates for creating views:
List
Create
Edit
Details
Delete
Some of the helper methods that can be used in building an MVC application are:
Html.ActionLink()
Html.BeginForm() and Html.EndForm()
Html.Label() and Html.LabelFor()
Html.DisplayNameFor() and Html.DisplayFor()
Html.TextBox() and Html.TextBoxFor()
Html.TextArea() and Html.TextAreaFor()
Html.EditorFor()
Html.Password() and Html.PasswordFor()
Html.HiddenFor()
Html.CheckBox() and Html.CheckBoxFor()
Html.DropDownList() and Html.DropDownListFor()
Html.RadioButton() and Html.RadioButtonFor()
Url.Action()
Chapter 4
Validating Data
In an MVC application, a model represents classes that interact with data. These classes contain various
properties, which define the structure of the data. To preserve this structure, you need to maintain the integrity of
the model. However, while interacting with a view, it is possible that users enter invalid data. Therefore, you need
to validate the data entered by users.
Validation is the process of checking the input data against certain criteria. In an MVC application, the data
entered by a user in a form is checked against the structure of the model class.
In order to validate the data, there are various data annotations provided by MVC, which help you to implement
validation.
This chapter discusses how to work with data annotations and implement data validation.
Objectives
The customer details, such as name, gender, and address, should be in the correct format and not left empty.
Moreover, the age entered by the customer in the registration form should be equal to or more than 18 years. In
such a situation, when the customer submits the form, the details of the customer must be validated. If the
validation criteria are valid, the form is accepted. Otherwise, an error message is displayed to the customer. Such
type of validation can be implemented on a website by using various data annotations available in the MVC
framework.
The advantage of using data annotations is that they enable you to perform validation efficiently by adding one or
more data annotation attributes to a model property. As a result, validation is easily performed.
Required
StringLength
RegularExpression
Range
Compare
Display
ReadOnly
DataType
ScaffoldColumn
Required
The Required data annotation attribute specifies that the property, with which this annotation is associated, is a
required property. This means that the value of the property cannot be left blank. This attribute raises a validation
error if the property value is null or empty.
Consider a scenario where you need to ensure that a user enters values for the username and the password fields,
before submitting the login Web page. To accomplish this task, you can use the Required attribute while
declaring the Username and Password properties in the Model class, as shown in the following code snippet:
[Required]
public string Username { get; set; }
[Required]
public string Password { get; set; }
In the preceding code snippet, the [Required] attribute is used before a property to validate the Username and
Password properties of a class. This attribute raises a validation error if the associated property value is either
null or empty. The validation errors raised through the data annotation attributes can be displayed to the user by
using validation helpers.
By using data annotation and validation helpers, a default message is displayed to the user, as shown in the
following figure:
The Output Showing Usage of the Required Attribute
In the preceding figure, the [Required] attribute raises a default error message. However, you can also
customize error messages. The following code snippet illustrates how to add a custom error message to the
[Required] attribute:
StringLength
The StringLength data annotation attribute is used to specify the minimum and maximum lengths of a string
field. The attribute raises a validation error, if the user enters a string with more or less number of characters than
the specified range. For example, consider the following code snippet:
However, if you want to display a custom message, you can use the following code snippet:
RegularExpression
At times, you need to accept user input in a specific text pattern. For example, if you want to accept an email
address, it is mandatory to have the @ symbol between the user name and the domain name. For this, you can
use a regular expression annotation attribute. It allows you to match a text string with a search pattern. The
pattern consists of one or more character literals, operators, or constructs. The regular expression has the
following syntax:
[RegularExpression("pattern")]
To check the validity of an email address, you can use the following regular expression pattern:
[RegularExpression(@"[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}")]
public string Email { get; set; }
In the preceding code snippet, the regular expression, [A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4},
is used to describe an email address.
An email address is divided into three segments arranged in the following manner:
[email protected]
Similarly, there are three segments in the given regular expression:
Segment1: [A-Za-z0-9._%+-]+
Segment2: [A-Za-z0-9.-]+
Segment3: [A-Za-z]{2,4}
The characters and character ranges specified within the square brackets in each segment specify the types of
characters that can appear in that segment.
The + sign at the end of Segment1 and Segment2 indicates that these segments can consist of one or more
characters of the types included within the square brackets preceding the + sign.
{2, 4} at the end of Segment3 indicates that the third segment can include 2-4 characters.
If a user does not enter the email in the correct format, the following error message is displayed.
Similarly, you can also create regular expressions to match other text patterns.
Range
You can use the Range attribute to specify the minimum and maximum constraints for a numeric value. For
example, if you want the user to enter the age between 20 and 35, you can use the Range attribute, as shown in
the following example:
You can specify the range for double values too, as shown in the following example:
Compare
At times, you have two fields in a form, in which you want to accept the same value. For example, you want that
a user should enter the same password in both, the Password and ConfirmPassword fields. Therefore, to match
the value of the two fields in a form, you can use the Compare attribute. This ensures that the two properties on a
model object have the same value. Consider the following example:
If a user does not enter the same password in both the fields, an error message is displayed, as shown in the
following figure.
When you use scaffolding to create views, the name of each property is displayed as a label for the fields
corresponding to that property. The Display attribute allows you to specify a user friendly display name for a
model property. For example, consider the following code snippet:
ReadOnly
At times, you want to display a read-only field on a form to the user. Consider the example of a form that allows
a user to enter a product code, price, and quantity of items. Once the user specifies the details, the total amount is
calculated and displayed to the user in the TotalAmount field. Because the value of the TotalAmount field is a
calculated value, the users need not calculate and enter the value of the total amount on their own. Therefore, you
can specify the TotalAmount field as read-only by using the ReadOnly attribute. This attribute ensures that the
default model binder will not set the property with a new value from the request. Consider the following
example:
[ReadOnly(true)]
public Int32 TotalMarks { get; set; }
In the preceding example, the TotalMarks property is set to read-only. If you use an EditorFor() helper for the
TotalMarks property, an enabled input will be displayed and the user will be able to enter a value in the input
element. However, the model binder will not set the property with a new value from the request.
DataType
The DataType attribute helps you to provide information about the specific purpose of a property at run time. For
example, a property of the string type can be used to hold an email address, a URL, or a password. By applying
DataType for a Password field as Password , the HTML helpers in ASP.NET MVC will render an input element
with a type attribute set to Password . Therefore, upon entering a value in the Password field, the user sees a
special character, such as a dot or star, instead of the original character. Consider the following example:
[DataType(DataType.Password)]
public string Password { get; set; }
In the preceding example, DataType of the Password field is set to Password , which displays a dot, instead of the
original character, as shown in the following figure.
The Password Field
You can also add other DataType attributes such as Currency , Date , Time , and MultilineText . To add
MultilineText to an Address field, consider the following example:
[DataType(DataType.MultilineText)]
public string Address { get; set; }
In the preceding example, DataType of the Address field is set to MultilineText , which displays a text area, as
shown in the following figure.
ScaffoldColumn
At times, you do not want to render a particular field on a view. For example, consider that you have the Age
property in your class. You want that when a user fills a form in a browser, the label and input for the Age field
should not be displayed on the browser. Consider the following example:
[Required]
[ScaffoldColumn (false)]
public string Age { get; set; }
With the preceding attribute in place, scaffolding will not add the the Age column to any view based on the
model.
Implementing Validation
Consider the scenario of the Newbay Web application. A user needs to enter values for the username and
password fields in a Login form before accessing the website. Once the user enters the username and the
password and submits the login form, it is sent to the server that validates the entered username and the
password. In case the username or the password contains a blank value, a value in an incorrect format, or a value
that does not match the credentials stored in the database, the server sends an error message to the client.
To check whether the credentials provided by the user match the credentials stored in the database, a round-trip
to the server is required. However, the other details, such as checking for blank values and correctly formatted
values, can even be done at the client side. Therefore, to avoid round trips to a server, you can implement
validation at the client- side.
Client-side validation provides immediate feedback without submitting anything to the server. It is usually
implemented using JavaScript. The data that the user enters is validated before being sent to the server. This
provides immediate feedback and an opportunity to correct any error before the data is sent to the server.
However, if JavaScript is disabled at the client-side, then the validation is only done at the server-side.
Both the client-and-server side validations, display a default message for an incorrect value. However, you can
change this default message by specifying the message in the corresponding annotation attribute. In addition, you
can summarize the entire validation message at one place, on a Web page. The error messages can be displayed
by using HTML validation helpers.
Let us see how to use these helpers to display error messages.
In the registration form of the Newbay application, a user needs to register personal details, such as user name,
password, email, city, and address. While filling the form, if the user enters an incorrect value in any of the
fields, an error message needs to be displayed to the user. To accomplish this task, MVC provides the following
two main helper methods:
Html.ValidationMessageFor()
Html.ValidationSummary()
Html.ValidationMessageFor
Consider the scenario where a registration form needs to be filled. While filling this form, if a user enters an
incorrect value in any of the fields, an error message is displayed separately for all the fields. To display these
error messages, the ValidationMessageFor() HTML helper is used with each field. For example, consider the
following model class:
{
public long ID { get; set; }
[Required]
public string Name { get; set; }
[Required]
[DataType(DataType.Password)]
public string Password { get; set; }
[Required]
[Compare("Password")]
[DataType(DataType.Password)]
public string Confirm { get; set; }
[Required]
[RegularExpression(".+\\@.+\\..+")]
public string Email { get; set; }
[Required]
public string City { get; set; }
[Required]
[DataType(DataType.MultilineText)]
public string Address { get; set; }
In the preceding code snippet, the model properties, such as Name , Password , Confirm, Email , City , and
Address , have different data annotations applied to them.
Based on the properties of the preceding model class, scaffolding will generate the following code for the
registration form:
@using (Html.BeginForm()) {
@Html.ValidationSummary(true)
<fieldset>
<legend>Customer</legend>
<div class="editor-label" >
@Html.LabelFor(model => model.Name)
</div>
<div class="editor-field" >
@Html.EditorFor(model => model.Name)
@Html.ValidationMessageFor(model => model.Name)
</div>
<div class="editor-label" >
@Html.LabelFor(model => model.Password)
</div>
<div class="editor-field" >
@Html.EditorFor(model => model.Password)
@Html.ValidationMessageFor(model => model.Password)
</div>
<div class="editor-label" >
@Html.LabelFor(model => model.Confirm)
</div>
<div class="editor-field" >
@Html.EditorFor(model => model.Confirm)
@Html.ValidationMessageFor(model => model.Confirm)
</div>
<div class="editor-label" >
@Html.LabelFor(model => model.Email)
</div>
<div class="editor-field" >
@Html.EditorFor(model => model.Email)
@Html.ValidationMessageFor(model => model.Email)
</div>
<div class="editor-label" >
@Html.LabelFor(model => model.City)
</div>
<div class="editor-field" >
@Html.DropDownListFor(model=>model.City,(SelectList)ViewBag.category,string.Empty)
@Html.ValidationMessageFor(model => model.City)
</div>
<div class="editor-label" >
@Html.LabelFor(model => model.Address)
</div>
<div class="editor-field" >
@Html.EditorFor(model => model.Address)
@Html.ValidationMessageFor(model => model.Address)
</div>
</fieldset>
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}
In the preceding code snippet, the @Html.ValidationMessageFor() helper method is used with each form field
to display the default error messages related to that field.
In the preceding code snippet, the @section directive is used to include the javascript libraries
required for implementing validation. You will learn more about the @section directive in the subsequent
chapters.
If a user submits the registration form without filling the values in the fields, the preceding code snippet will
render the following interface:
The Output Showing the Default Error Along with the Fields
However, you can replace the default messages for the individual fields by short messages or a special character,
such as asterisk (*). In order to implement this functionality, you need to pass the short message as the second
parameter of the Html.ValidationMessageFor() helper method, as shown by the highlighted part of the
following code snippet:
@using (Html.BeginForm()) {
@Html.ValidationSummary(true)
<fieldset>
<legend>Customer</legend>
<div class="editor-label">
@Html.LabelFor(model => model.Name)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Name)
@Html.ValidationMessageFor(model => model.Name, "*")
</div>
<div class="editor-label">
@Html.LabelFor(model => model.Password)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Password)
@Html.ValidationMessageFor(model => model.Password, "*")
</div>
<div class="editor-label">
@Html.LabelFor(model => model.Confirm)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Confirm)
@Html.ValidationMessageFor(model => model.Confirm, "*")
</div>
<div class="editor-label">
@Html.LabelFor(model => model.Email)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Email)
@Html.ValidationMessageFor(model => model.Email, "*")
</div>
<div class="editor-label">
@Html.LabelFor(model => model.City)
</div>
<div class="editor-field">
@Html.DropDownListFor(model=>model.City,(SelectList)
ViewBag.category,string.Empty)
@Html.ValidationMessageFor(model => model.City, "*")
</div>
<div class="editor-label">
@Html.LabelFor(model => model.Address)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Address)
@Html.ValidationMessageFor(model => model.Address, "*")
</div>
</fieldset>
}
If a user submits the registration form without filling the values in the fields, the preceding code snippet will
render the following output:
The Output Showing an Asterisk Character Instead of the Default Error Message
A short error message is usually displayed with the form fields when you want to display the detailed
error messages together at one place by using the Html.ValidationSummary() helper method.
Html.ValidationSummary
The Html.ValidationFor() helper can be associated with a single form field, and it will display the errors
associated with that field. Therefore, you need a separate ValidationFor() helper for each form field. If you
want to summarize all the error messages at one place, you can use the Html.ValidationSummary() helper. In
order to implement this functionality, you need to add the highlighted code snippet in the view file, as shown in
the following code:
@using (Html.BeginForm()) {
@Html.ValidationSummary(false)
In the preceding code snippet, the value, false , indicates that the validation messages for each individual
property should not be excluded while displaying the validation summary. As a result, the validation messages for
all the properties will be displayed together in the validation summary.
The validation summary for the preceding example will show the summarized error messages, as shown in the
following figure.
Introduction to ModelState
Consider a situation where a user needs to enter the username and password before accessing a Web page. Once
the user enters the password in the correct format, the entered password will be bound with the password
property in the model class. This process is known as model binding. However, if the user enters the password in
an incorrect format, the process of binding the password with the password property of the model class fails. This
results in an error. The error message associated with this error can be displayed by using the
ValidationMessage helper method. If the model binding succeeds, the ModelState.IsValid property returns
true. However, if there is any error in the model state, the ModelState.IsValid property returns false.
if (ModelState.IsValid)
{
//Code to save the entered data and display an appropriate view
}
else
{
//Code to redisplay the view with errors
}
In the preceding code snippet, if ModelState.IsValid is true, the data entered by the user is saved. Otherwise,
the view is redisplayed with errors.
[HttpPost]
if (usernameAlreadyExists(credentials.Username))
{
ModelState.AddModelError("Username", "Username is not available.");
}
if (ModelState.IsValid)
{
/*Code to save the entered data and display an appropriate view */
}
else
{
//Code to redisplay the view with errors
}
}
In the preceding code snippet, the Username property of the credential object is passed to a user-defined
function, usernameAlreadyExists() , which checks whether the username provided by the user already exists or
not. If the username already exists, an error message indicating the same is added to ModelState . If the model
state contains an error, the ModelState.IsValid property returns false. However, if the model state does not
contain any error, the ModelState.IsValid property returns a true value and the data entered by the user is
saved.
Summary
In this chapter, you learned that:
Validation is the process of checking the input data against certain criteria.
Some of the commonly used data annotations are:
Required
StringLength
RegularExpression
Range
Compare
Display
ReadOnly
DataType
The Required data annotation attribute specifies that the property, with which this annotation is
associated, is a required property.
The StringLength data annotation attribute is used to specify the minimum and maximum lengths of a
string field.
You can use the Range attribute to specify the minimum and maximum constraints for a numeric value.
The Display attribute allows you to specify a user friendly display name for a model property.
The DataType attribute helps you to provide information about the specific purpose of a property at run
time.
Client-side validation provides immediate feedback without submitting anything to the server.
Both the client-and-server side validations, display a default message for an incorrect value.
MVC provides the following two main helper methods:
Html.ValidationMessageFor()
Html.ValidationSummary()
The Html.ValidationFor() helper can be associated with a single form field, and it will display the
errors associated with that field.
Chapter 5
Managing Data
Most Web applications handle data available as a database, text file, xml file, or spreadsheet. To access this data,
an application needs to interact with the relevant data source. In an application, data is usually stored in the form
of classes and objects. However, in a database, data is stored in the form of tables and views. Therefore, the
definitions of classes or objects need to be mapped with the database tables or relational schemata. This requires
you to write additional code. To overcome this problem, Entity Framework can be used. Entity Framework maps
the classes and objects in an application to the tables in a relational data store. Moreover, it eliminates the need
to write most of the data access code that needs to be written otherwise.
This chapter discusses the fundamentals of Entity Framework. In addition, it explains how to work with Entity
Framework to manage data in an application.
Objectives
To overcome this problem, .NET provides the Object-Relational Mapping (ORM) framework called Entity
Framework. Entity Framework enables you to work with relational data in the form of objects by representing the
relational objects, such as tables, views, stored procedures, and functions, in the form of a conceptual model in
the application. The conceptual model represents data as entities and relationships among these entities. In an
Entity Framework-based application, the conceptual model is referred to as Entity Data Model (EDM). EDM
allows you to work with data as entities or objects.
Entity Framework eliminates the need to write most of the data-access code that otherwise needs to be written. It
uses different approaches to manage data related to an application. These approaches are:
While developing an application, if you already have an existing database, the database-first approach is
considered to be the best-suited approach. Entity Framework uses the database and generates the model for you,
as depicted by the following figure.
The resulting data model will contain all the classes and properties corresponding to the existing database objects,
such as tables and columns. The database structure and model related information are stored in an XML file with
the .edmx extension. You can generate, edit, and update the .edmx file by using the Entity Framework designer
provided by Visual Studio. The Entity Framework designer is a graphical designer tool that enables you to modify
the .edmx file. This tool is used to visually create and change entities and associations.
If you don't have a database and you are at the initial stages of development, you can follow the model-first
approach. In the model-first approach, the first priority is the model, while the code and the database are
secondary. The model-first approach gives you the flexibility to delay the creation of a database and, hence,
allows you to view the different possibilities of improving its structure.
In the model-first approach, you can first create a model by using the Entity Framework designer. The resulting
model and mapping information are stored in the .edmx file. The following figure displays a model created by
using the Entity Framework designer.
While creating a model, you can create entities, relationships between two entities, and inheritance hierarchies.
Once the model is created, the Entity Framework designer uses the .edmx file of the model to create the
database, as depicted by the following figure.
The Model-first Approach
In the code-first approach, you can start the development of your application by coding custom classes and
properties, which correspond to tables and columns in the relational database. This approach allows you to build
a database without using the Entity Framework designer or the .edmx file.
In the code-first approach, if you don’t have an existing database, you first create your own custom classes, and
then the database is created from them automatically. Further, if you change the model class, Entity Framework
provides you the options to drop and recreate the database accordingly.
If you have an existing database, you can still define classes that map to the existing database. In addition,
reverse engineering tools are available that allow you to generate the model classes from the existing database.
The code-first approach allows you to define your own domain model by creating custom classes. The database is
then created by using this model. The structure of the database is determined by examining the structure of the
model and using certain conventions.
Let us discuss the conventions used for the code-first approach. In addition, let us see how to implement the
Entity Framework code-first approach.
The code-first approach allows you to provide the description of a model by using the C# or Visual Basic .NET
classes. Based on these class definitions, the code-first conventions detect the basic structure of a model. The
code-first conventions are a set of rules that automatically configure a conceptual model. These conventions are
defined in the System.Data.Entity.ModelConfiguration.Conventions namespace . Some of the conventions
are:
Table naming convention: If you have created an object of the model class named Customer and want
to store its data in the database, Entity Framework assumes that you want to store the data in the table
named Customers .
Primary key convention: If in a class, you have created the property named ID or <classname> ID, the
property is assumed to be a primary key. Also, Entity Framework sets up an auto-incrementing key
column in SQL Server to hold the property value.
Consider the following code snippet:
In the preceding code snippet, you have created the property, ID, inside the class named Customer .
Therefore, it is inferred as a primary key.
In the preceding code snippet, the CustomerID property will be inferred as a primary key. This is
because the name of the property contains the class name followed by ID.
Relationship convention: Entity Framework also follows certain conventions to identify a relationship
between two entities. A relationship between two entities can be defined by using navigational
properties. In addition to the navigational properties, it is recommended to define a foreign key property
on types that represent dependent objects. For example, consider the following code snippet:
public class Customer
{
public int ID { get; set; }
In the preceding code snippet, Orders is the navigational property in the Customer class and cust is the
navigational property in the Order class. We call these as navigational properties because they allow us
to navigate to the properties of another class. For example, by using the navigational property, cust , you
can navigate to the orders associated with that customer. One customer can place multiple orders.
Therefore, the orders navigational property is declared as a collection. This indicates a one-to-many
relationship between the Customer and Order classes.
In addition, a property by the name, CustomerID , is included in the Order class. This property is inferred
by Entity Framework as a foreign key.
Entity Framework uses certain conventions to identify a foreign key. Entity Framework infers that a
property is a foreign key, if it meets the following conditions:
The property has the same data type as the principal primary key. For example, the CustomerID
property in the Order class has the same data type as the principal primary key, CustomerID , in the
Customer class.
The name of the property follows any one of the following formats:
<navigational property name><principal primary key property name>: As per this
format, a valid name for the foreign key in the Order class could be custCustomerID .
<principal class name><principal primary key property name>: As per this format, a
valid name for the foreign key in the Order class could be CustomerCustomerID .
<principal primary key property name>: As per this format, a valid name for the foreign
key in the Order class could be CustomerID .
If there are multiple properties that match the given formats, the precedence is given in the order the preceding
formats are listed.
You can use the code-first approach by performing the following steps:
In the preceding code snippet, the class named Customer is created. The Customer class defines various
properties, such as ID, Name , Gender, Address, and Email .
In addition, the following class can be created to describe the data related to products:
In the preceding code snippet, the class named Product is created. The Product class defines various properties,
such as ID, Name , and Description.
{
public DbSet<Customer> Customers { get; set; }
public DbSet<Product> Products { get; set; }
}
In the preceding code snippet, the database context class named ShopDataContext is created. It is derived from
the DBContext class defined in the System.Data.Entity namespace. This class creates the DBSet property for
both, the Customer class and the Product class.
The connection string can have various connection string properties. Some of the important connection string
properties are:
Data Source: It indicates the name or the IP address of the server where the data source is located.
Initial Catalog: It indicates the name of the database that will be accessed by using the specified
connection.
Integrated Security: You can connect to SQL Server by using either the Windows authentication or
the SQL Server authentication. The Integrated Security property indicates that you want to connect
to SQL Server by using the Windows user account. The possible values for this property are True ,
False , and SSPI . The True and SSPI (Security Support Provider Interface) values specify that the
current Windows account credentials need to be used for user’s authentication. However, SSPI provides
better security. The False value specifies that the SQL Server authentication needs to be used.
SSPI is an Application Programming Interface (API) that Microsoft Windows uses to handle
security-related operations.
Persist Security Info: It indicates whether the user-related information, such as the user ID and
password, is discarded once used to open the connection. This information is discarded when the value
of Persist Security Info is set to False . However, if the value of this attribute is set to True, the
security-sensitive information, including the user ID and password, can be obtained from the connection
after the connection has been opened. This may lead to serious security issues as the login information
can be leaked out as long as the connection is open.
AttachDBFilename: It gets or sets a string that contains the name of the primary data file.
providerName: It is an optional attribute that specifies a class to communicate with a specific type of
data source.
To define a connection string, you need to open the Web.config file and add a new connection string within the
<connectionStrings> and </connectionStrings> tags, as shown in the following code snippet:
<connectionStrings>
...
...
<add name="ShopDBConnection" connectionString="Data Source=(LocalDb)\v11.0;Initial
Catalog=aspnet-NewbayOnline-20130416063703;Integrated
Security=SSPI;AttachDBFilename=|DataDirectory|\aspnet-NewbayOnline-20130416063703.mdf"
providerName="System.Data.SqlClient" />
</connectionStrings>
The preceding code snippet specifies the connection string named ShopDBConnection. This connection string
specifies that the data source, (LocalDb)\v11.0 , and the SQL Server database named aspnet-NewbayOnline-
20130416063703.mdf need to be used to store the data.
Afterwards, you can specify the connection string to be used by adding a constructor in the DbContext class. For
example, consider the following code snippet:
{
public ShopDataContext()
: base("ShopDBConnection")
{
}
}
In the preceding code snippet, the connection string named ShopDBConnection is specified by using the
constructor in the ShopDataContext() class. As a result, a connection to the database will be established by
using the ShopDBConnection connection string.
Creating a Controller
You can create a controller either by using scaffolding or by writing the code manually. For creating the
controller automatically by using scaffolding, you need to specify the scaffolding template, model class name,
and data context name. One of the scaffolding templates creates an MVC controller with the various action
methods and the corresponding views. These action methods handle the create, edit, display, and delete
operations in a database. However, you can also create these methods manually in an empty controller according
to your needs. Let us discuss these action methods one by one.
Consider the following Index() action method that retrieves customer records and renders an appropriate view:
In the preceding action method, first the instance, db, of the ShopDataContext class is created. Next, this
instance is used to retrieve the customer records and store them in the collection variable, customers . Finally, the
View() method is invoked to render a view and the customers collection is passed to the view as a parameter.
The preceding Index() method uses Language Integrated Query (LINQ) to retrieve customer records
from the database. You will learn more about LINQ in the next chapter.
{
return View();
}
The preceding method returns a view that displays a form to enter customer records, as shown in the following
figure.
The preceding action method accepts the id of the record to be edited as a parameter. It then uses the Find()
method to find the customer record on the basis of the primary key, id. If the customer record is found, the view
for editing the customer record is rendered. Otherwise, the HttpNotFound() method is invoked, which informs
you that the requested resource is not found.
The other Edit () action method is invoked whenever the HTTP POST request is received from the Edit view.
This action method first validates the data entered by the user, and then saves the updated data. For example,
consider the following method:
[HttpPost]
In the preceding code, the Find() method is used to find the customer record on the basis of the primary key, id.
If the customer record is found, the view containing the customer record is rendered. Otherwise, the
HttpNotFound() method is invoked, which informs you that the requested resource is not found.
{
Customer customer = db.Customers.Find(id);
if (customer == null)
{
return HttpNotFound();
}
return View(customer);
}
The HTTP POST version of the Delete() action method requires the same signature as that of the HTTP GET
version of the Delete() action method. However, CLR requires overloaded methods to have unique signatures.
To resolve this problem, the HTTP POST method is named as DeleteConfirmed . The DeleteConfirmed()
action method deletes the required record, and then saves the changes in the database. For example, consider the
following code snippet:
[HttpPost, ActionName("Delete")]
The preceding DeleteConfirmed() action method is preceded with the ActionName("Delete") attribute. This
attribute is added to perform mapping for the routing system so that a URL that includes /Delete/ for a POST
request will be routed to the DeleteConfirmed() action method. In the DeleteConfirmed() action method, the
Remove() method is used to delete a customer record and the SaveChanges() method is used to save the changes
to the database. Finally, the code redirects the user to the Index() action method of the controller. The Index()
action method displays the customers’ records, which exclude the deleted record.
Depending on the need, you can select one of the preceding classes while calling the SetInitializer() method
of the System.Data.Entity.Database namespace. For example, if you want to recreate the NewBay store
database whenever the application starts, you need to write the highlighted portion of the following code inside
the Global.asax.cs file:
Database.SetInitializer(new DropCreateDatabaseAlways<ShopDataContext>());
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
}
In the preceding code, the DropCreateDatabaseAlways class is used while calling the SetInitializer()
method. This ensures that the existing database is recreated whenever the application starts.
However, if you want to recreate the NewBay store database only when the model changes, you need to use the
highlighted portion of the following code inside the Global.asax.cs file:
Database.SetInitializer(new DropCreateDatabaseIfModelChanges<ShopDataContext>());
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
}
In the preceding code, the DropCreateDatabaseIfModelChanges class is used while calling the
SetInitializer() method. This ensures that the existing database is recreated whenever the model changes.
At the time of development, you can instruct Entity Framework to initialize your database with some sample data
for testing purposes whenever the database is recreated. For this, you need to create a model class that derives
from either the DropCreateDatabaseIfModelChanges class or the DropCreateDatabaseAlways class. In this
class, you need to override the Seed() method. The Seed() method enables you to define the initial data for the
application.
Consider the following code snippet that defines the MyDataContextDbInitializer class:
In the preceding code snippet, the MyDataContextDbInitializer class in derived from the
DropCreateDatabaseIfModelChanges class. In the MyDataContextDbInitializer class, the Seed() method is
overridden to define the initial data for the customers.
Then, you need to register the MyDataContextDbInitializer class while calling the SetInitializer() method.
For this, you need to add the highlighted portion of the following code snippet in the Application_Start()
method in the Global.asax.cs file:
System.Data.Entity.Database.SetInitializer(new MyDataContextDbInitializer());
}
You need to ensure that the required namespaces are included. Otherwise, the code will not run.
The approach of recreating a database whenever the application starts or the model changes will lead to the
deletion of existing data. Therefore, this approach is applicable only in the development phase when you are
working with some sample data. However, when the Web application becomes live, you need a mechanism that
enables you to prevent the loss of data. For this, Entity Framework supports code-first migrations. It allows you
to change the model and modifies the database accordingly. For example, you have created the Customer model
with the properties, such as Name , Address, and Gender. Now, you want to add additional properties named City
and PhoneNumber in the Customer model. A database migration allows you to add the column in the database
without dropping the database, thereby retaining the data saved in the database. To enable database migration,
you need to use Package Manager Console. You can use Package Manager Console to:
Enable migrations
Run migrations
Enabling Migrations
To enable migrations, you need to run the following command in Package Manager Console:
Enable-Migrations
If more than one context is used in the application, you need to specify the context name. For example, consider
the following command:
In the preceding code snippet, the ShopDataContext class is specified as the context name while running the
Enable-Migrations command.
On execution, this command adds the Migration folder to the project. This Migration folder contains the
following two files:
The Configuration class: This class enables you to configure how the migrations will behave for the
data context. It contains the Seed() method that can be modified according to your needs. To use the
Configuration class and modify the Seed() method, you first need to set the
AutomaticMigrationsEnabled variable to true in the Configuration() method of the Configuration
class file, as shown in the following code snippet:
public Configuration()
{
AutomaticMigrationsEnabled = true;
}
Thereafter, you can modify the Seed() method in the Configuration class file, as shown in the following
code snippet:
{
context.Customers.AddOrUpdate(r => r.Name, new Customer { Name = "abc", Gender =
"Male" });
}
The preceding code snippet will add the customer record to the database only if the record does not
already exist. However, if the record related to that customer already exists, it will be updated if there is
any modification in the record.
If you have registered the model class for initializing the database with the test data, you need
to comment the SetInitializer statement in the Application_Start() method of the
Global.asax.cs file.
An InitialCreate migration script: This migration script is only added in the project when you already
have a database, before you enable migrations. It contains two methods, Up() and Down(). The Up()
method contains the code to migrate the database to your new model, and the Down() method contains
the code to undo the change and revert back to the previous version.
Running Migrations
You can run migration by using the Update-Database command. This command updates the database by
applying the pending migrations. For example, if you have added a new property in the model, the following
command can be used to update the database:
Update-Database -Verbose
In the preceding command, the -Verbose flag is used to view the SQL statements that are being applied to the
target database.
Entity Framework enables you to work with relational data in the form of objects by representing the
relational objects, such as tables, views, stored procedures, and functions, in the form of a conceptual
model in the application.
While developing an application, if you already have an existing database, the database-first approach
is considered to be the best-suited approach.
In the model-first approach, the first priority is the model, while the code and the database are
secondary.
In the code-first approach, you can start the development of your application by coding custom classes
and properties, which correspond to tables and columns in the relational database.
A relationship between two entities can be defined by using navigational properties.
You can use the code-first approach by performing the following steps:
a. Create the model classes.
b. Create the database context.
c. Configure the database location.
d. Create a controller.
A connection string specifies information about a data source and the way to establish a connection.
Entity Framework provides the following two classes in the System.Data.Entity namespace:
DropCreateDatabaseAlways
DropCreateDatabaseIfModelChanges
A database migration allows you to add the column in the database without dropping the database,
thereby retaining the data saved in the database.
You can use Package Manager Console to:
Enable migrations
Run migrations
Chapter 6
Using LINQ to Access Data
While developing data-centric applications, you need to deal with two types of code, the business logic
implementation code and the data manipulation code. The business logic implementation code is written by using
a programming language. However, traditionally, the data manipulation code includes queries written in a data-
source-specific query language. Therefore, in order to develop a data-centric application, you need to learn a
programming language as well as a query language. In addition, if the data source of an application changes, you
need to learn a different query language and modify the data manipulation code of your application.
To overcome these issues, Microsoft introduced Language Integrated Query (LINQ). LINQ enables you to create
data-source-independent queries in an application and offers different providers to work with different data
sources.
This chapter explains how to work with LINQ. Further, it discusses how to use LINQ to access data from
disparate data sources, such as SQL, XML, and business objects.
Objectives
Introduction to LINQ
Traditionally, an application that needed to access data from a database used to include database-specific queries
in a string format within the application code. For example, consider the following code snippet that creates an
application object for storing a query that retrieves data from the Product table:
LINQ simplifies this situation by offering a consistent model for working with data across the various kinds of
data sources and formats.
LINQ is a set of APIs that enables you to create data-source-independent queries to implement data access in an
application. It has a programming model that provides the standard query syntax to query different types of data
sources. In LINQ, the query is written in any .NET Framework supported programming language, such as C# or
VB. The LINQ query acts on a strongly-typed collection of objects with the help of language keywords and
common operators. This helps developers to quickly manipulate data from the various data sources without
requiring them to learn a new query language.
Using a Simple LINQ Query
LINQ offers a consistent programming model to query data from different data sources. So, the same query
syntax is used to query and alter data in the various data sources. Therefore, all LINQ query operations consist of
the same set of actions that act on different data sources. All LINQ query operations consist of the following
three distinct actions:
Consider the scenario of the Newbay application wherein you need to retrieve customer details from the
Customer table stored in an SQL Server database. In this application, you can use an instance of the
IQueryable<T> interface to retrieve the customer details from the data source, as shown in the following code
snippet:
The select clause in a LINQ query specifies the type of the returned elements. Using the select clause, you can
specify whether your result will consist of complete customer objects, a subset of the members of the customer
object, or some computed values. The select clause in the preceding LINQ query specifies that each element in
the result will consist of a customer object.
Deferred execution helps you to create a query once, and then execute it as many times as you want. It is useful
in situations where the database is constantly updated. In such a situation, you can create a query variable and
execute it repeatedly at some interval to retrieve the updated data.
For example, to retrieve and display the customer details from the Customers table of an SQL Server database,
you need to first create a query. Next, you need to use the foreach statement to execute the query and retrieve
the details, as shown in the following code snippet:
Queries that perform aggregate functions, such as Max and Count , over a range of source elements, execute
without explicitly using the foreach loop and return a single value. These queries are executed at the time of
their definition. This is called immediate execution. For example, to count the number of customer records in the
db.customers data source, consider the following code snippet:
You can also force immediate execution by calling the ToList<TSource>() or ToArray<TSource>() methods.
The ToList<TSource>() method forces immediate query execution and returns List<T> that caches the query
results. Consider the following example, which forces immediate query execution and returns List<T> that
contains the query results:
The ToArray<TSource>() method forces immediate query execution and returns an array that caches the query
results. Consider the following example, which forces immediate query execution and returns an array that
contains the query results.
In addition to selecting data, a query can perform the following operations on data:
Consider the scenario of Newbay wherein you need to filter only those customers who have an address in Tokyo.
This requires you to retrieve the records from the Customer table. For this, you need to use the from and where
clauses in the query, as shown in the following code snippet:
In addition, you can use the logical operators, such as AND (&&) and OR (||), to apply multiple filters as
necessary in the where clause. For example, to filter the customers who live in Tokyo and have the name, Tom,
you need to use the following code snippet:
IQueryable<Customer> q = from s in db.customers
where s.City == "Tokyo" && s.Name == "Tom"
select s;
In the preceding code snippet, the AND (&&)operator is used to apply multiple filters.
Consider the scenario of Newbay wherein you need to sort the names of the customers who live in Tokyo in the
ascending order. This requires you to retrieve the records from the Customer table. For this, you need to use the
ascending keyword along with the orderby clause, as shown in the following code snippet:
To sort the records in the descending order, you need to explicitly use the descending keyword in the query. In
order to sort the customer records in the descending order of name, you need to use the descending keyword in
the query, as shown in the following code snippet:
Consider the scenario of Newbay wherein you need to group the customers by the city name so that all the
customers from a particular city, such as Tokyo or London, are arranged in individual groups. To group the
customers according to their cities, you need to use the following code snippet:
Consider the scenario of Newbay wherein you need to retrieve the records of all the male customers who have
placed an order online. This requires you to retrieve information from the customers table and the orderdetails
table. For this, you can use the join clause in the query, as shown in the following code snippet:
Query syntax
Method syntax
The syntax that you have been using until now is called the query syntax. The query syntax is the most
commonly-used technique to write a LINQ query. This syntax is written in the form of a query expression. Such
expressions are simple and easy to read.
A query expression written by using the query syntax is translated into method calls at the time of compilation.
The method calls finally invoke the standard query operators, such as Where , Select, and GroupBy. However, you
can directly invoke the query operators by using the method syntax.
The method syntax specifies an exact order in which the methods in a query are to be called. For this, the method
syntax uses the standard method invocation, using which the standard query operators, such as Where , Select,
and GroupBy, are directly called. In addition, the method syntax is used in cases where a single numeric value is
returned, such as Sum, Max, Min, and Average. These methods must always be called last in any query because
they represent only a single value and cannot serve as the source for an additional query operation.
Let us consider an example of a LINQ query that uses the method syntax:
LINQ to SQL
LINQ to XML
LINQ to Objects
LINQ to SQL
LINQ to SQL enables you to access SQL-complaint databases and makes data available as objects in an
application. These objects in the application are mapped with the database objects to enable you to work with
data.
The object model of the programming language and the data model of the relational database are mapped to each
other. You can perform all the database operations, such as select, insert, update, and delete, on a database with
the help of mapped objects.
On executing a LINQ to SQL query to retrieve the data from a database, the LINQ to SQL queries are converted
into SQL queries. These queries are sent to the database where the database query execution engine executes the
queries and returns the results. These results are converted back to objects by using LINQ to SQL, and then sent
to the application.
During this process, LINQ to SQL uses an instance of the data context class of the application to cache the data
retrieved from the database and send the data to the application. In addition, LINQ to SQL uses the instances of
the model class to represent the tables of the database in the application.
The following example describes how to access the names of the customers of Newbay Store from the Customer
table:
LINQ to XML
LINQ to XML is a LINQ-enabled, in-memory XML programming interface that enables you to work with XML
from within the .NET Framework programming languages. XML is widely used to exchange data between
various applications. LINQ to XML is a programming interface that enables you to access data stored in XML
files. The following example shows the content of the XML file, CustomersDetails.xml :
LINQ to Objects
LINQ to Objects refers to the use of LINQ queries with enumerable collections, such as List<T> or arrays.
Traditionally, you had to write the foreach loops to retrieve data from enumerable collections. LINQ to Objects
provides an easier way to retrieve data from object collections by using standard queries.
To use LINQ to query an object collection, you need to declare a range variable. The type of the range variable
should match the type of the objects in the collection. For example, if you create an array that stores objects of
the type, Customer , the range variable should also be of the type, Customer , as shown in the following code
snippet:
The following example describes how to access data from a string array that contains the names of students in a
class:
Summary
In this chapter, you learned that:
LINQ offers a consistent programming model to query data from different data sources.
All LINQ query operations consist of the following three distinct actions:
Obtain the data source
Create the query
Execute the query
In addition to selecting data, a query can perform the following operations on data:
Filter the data
Sort the data
Group the data
Join the data
LINQ queries in C# can be written by using two different syntaxes:
Query syntax
Method syntax
LINQ provides a consistent programming model using which you can create the standard query syntax
to query different types of data sources.
Some LINQ providers are:
LINQ to SQL
LINQ to XML
LINQ to Objects
Chapter 7
Implementing a Consistent Look and Feel Across an MVC Web
Application
You can create a website by creating several Web pages connected to each other. However, a professional
website requires more than creating individual Web pages and connecting them. The look and feel of all the Web
pages in a website should be consistent. All the pieces of information should appear in a standard, consistent
format across all the Web pages. In addition, the Web pages should have a standard layout.
To maintain a standard layout in the MVC applicahtion, you can use layouts. In addition, you can enhance the
appearance of a Web application by implementing styles on it.
This chapter discusses how to implement a consistent look and feel across all the Web pages by using layouts. In
addition, it discusses how to style views.
Objectives
To implement the preceding requirement, you need to copy the navigation bar links on each view individually.
You also need to ensure that the navigation bar is placed at the same position on all the views to maintain a
consistent look and feel. In addition, any change in the navigation bar at a later stage will require changes to be
made on each view of the website. This is a complex and time-consuming process. This process can be
simplified and made efficient by using layouts.
A layout is a feature that enables you to specify a common site template to be used across the views of a website.
Layout defines the structure and common ingredients of the views. You can use a layout with the selected views
in a website or with all the views in a website.
The process of creating a layout in an ASP.NET MVC application is similar to the process of creating a view.
However, the only difference is that in case of an ASP.NET MVC application, you need to add a layout file in
the Shared folder under the Views folder. As a convention, the name of the layout file is preceded by the
underscore (_) character. Similar to a view, the extension of a layout file is .cshtml.
A layout file defines the visual components that are common across a set of views. In addition, it defines
placeholders for the unique content associated with each individual page.
A Layout
With reference to the preceding figure, suppose that the top bar, navigation bar, and footer contain some static
content to be rendered in each view. However, the body and the side bar are specific to each view. This means
that the content for the body is provided by the main content of each individual view, and the content for the
sidebar is provided as the content for a specific section by each individual view.
To define the content for the body and section in a layout, you need to design a view, as shown in the following
code snippet:
To render the unique content associated with a view in the layout, the following methods can be used:
The @RenderBody() method
The @RenderSection() method
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>@ViewBag.Title - My ASP.NET MVC Application</title>
</head>
<body>
<div id="body">
@RenderBody()
</div>
</body>
</html>
In the preceding code, the call to the @RenderBody() method inside the <div> tag inserts the main content of the
view.
<!DOCTYPE html>
<html>
<head><title>@ViewBag.Title</title></head>
<body>
<h1>@ViewBag.Title</h1>
<div id="main-content">@RenderBody()</div>
<div>@RenderSection("Section1")</div>
</body>
</html>
The sections specified in a layout must be defined in all the views that use the layout.
However, if you do not want to use those sections in some of the views, you can use an overloaded method of the
@RenderSection() method in your layout. The overloaded method of @RenderSection() uses the required
attribute with the false value, as shown in the following code snippet:
<div>@RenderSection("Section1", required: false)</div>
The preceding @RenderSection() method indicates that a view that uses this layout may supply content for a
section named Section1. However, this is not mandatory. A view that uses this layout may not contain any
section named Section1 .
However, a better approach is to use some default content for the section that can be used in case a view does not
provide content for the section. For this, you can use the following code in the layout:
<div>
@if (IsSectionDefined("Section1")) {
RenderSection("Section1");
}
else {
<span>This is the default section content</span>
}
</div>
The preceding code snippet renders a section named Section1 if it is defined in a view. However, if the section,
Section1 , is not defined in the view, the message, This is the default section content , is rendered in the
view.
Task 7.1: Creating a Layout
You can specify a layout for either each individual view or for all the views on a website. A layout can be
specified for a view by using the Layout property, as shown in the following code snippet:
@{
Layout = "~/Views/Shared/MyLayout.cshtml";
}
In the preceding code snippet, the MyLayout.cshtml file is specified as the layout for the view that contains the
preceding code snippet.
However, if you want to specify a particular layout for all the views of the website, then you can specify the
layout to be used in the _ViewStart.cshtml file. This file is located inside the Views folder.
The code specified in the _ViewStart.cshtml file is executed before the code in any view, which is placed in the
same directory or within a sub-directory. It applies the layout specified in the _ViewStart.cshtml file to all the
views in the same directory/subdirectories. However, a view can override the Layout property by specifying a
different value for the property.
When you create a default ASP.NET MVC project by using any template except the Empty template, an
_ViewStart.cshtml file is already present in the Views folder. This file specifies the default layout to be used, as
shown in the following code snippet:
@{
Layout = "~/Views/Shared/_Layout.cshtml";
}
In the preceding code snippet, the default layout is specified as _Layout.cshtml .
The _Layout.cshtml file is a default layout file that is included as part of the ASP.NET MVC project, which is
created by using any template except the Empty template. It represents the layout that can be applied to the
selected views or to all the views. This file is located in the Shared folder under the Views folder of the
application.
The _Layout.cshtml file contains the basic structure of a view. If you create a project by using the Internet
template, the _Layout.cshtml file contains the following code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>@ViewBag.Title - My ASP.NET MVC Application</title>
<link href="~/favicon.ico" rel="shortcut icon" type="image/x-icon" />
<meta name="viewport" content="width=device-width" />
@Styles.Render("~/Content/css")
@Scripts.Render("~/bundles/modernizr")
</head>
<body>
<header>
<div class="content-wrapper">
<div class="float-left">
<p class="site-title">@Html.ActionLink("your logo here", "Index", "Home")</p>
</div>
<div class="float-right">
<section id="login">
@Html.Partial("_LoginPartial")
</section>
<nav>
<ul id="menu">
<li>@Html.ActionLink("Home", "Index", "Home")</li>
<li>@Html.ActionLink("About", "About", "Home")</li>
<li>@Html.ActionLink("Contact", "Contact", "Home")</li>
</ul>
</nav>
</div>
</div>
</header>
<div id="body">
@RenderSection("featured", required: false)
<section class="content-wrapper main-content clear-fix">
@RenderSection("JavaScript", required: false)
@RenderBody()
</section>
</div>
<footer>
<div class="content-wrapper">
<div class="float-left">
<p>© @DateTime.Now.Year - My ASP.NET MVC Application</p>
</div>
</div>
</footer>
@Scripts.Render("~/bundles/jquery")
@RenderSection("scripts", required: false)
</body>
</html>
The preceding code snippet contains the @RenderBody() method and multiple @RenderSection() methods.
These methods act as placeholders for the page-specific content appearing on each view. In addition, it contains
the @Styles.Render("~/Content/css") statement that renders the css files. In addition, it contains the
@Scripts.Render("~/bundles/modernizr") statement that renders the script files in the modernizr library.
Moreover, it contains the Scripts.Render("~/bundles/jquery") statement that renders the jQuery library.
You can modify the _Layout.cshtml file according to your need for developing an MVC application. For
example, you can add/delete hyperlinks, change the layout color, and include/exclude sections.
Layouts are used to standardize the look and feel of all the views on a website. However, sometimes, it is
required that some of the views on a website should follow certain standard features, apart from the features
provided by the global layout. In such situations, you can implement nested layouts.
Consider an example where a website uses a layout for displaying the navigation bar. Apart from the navigation
bar provided by the layout, some of the views on the website require a sidebar to be displayed on the left side of
the Web page. This can be implemented by using a nested layout.
A nested layout page refers to a layout that is derived from a parent layout. It is similar to the layout page and is
responsible for defining the structure of a page. Similar to layouts, a nested layout page needs to call the
@RenderBody() method once and can have multiple sections that can be rendered by using the
@RenderSection() method. However, the Layout directive in a nested layout page contains the reference of the
parent layout page. For example, consider the parent layout page named _ParentLayout.cshtml that contains the
following code:
@{
ViewBag.Title = "_ParentLayout";
}
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<div>
<table style="width: 100%; font-family: 'Monotype Corsiva'">
<tr style="background-color: darkblue">
<td style="width: 200px">
<img src="~/Images/logo1.jpg" width="100" height="100"/></td>
<td style="font-size: 50px; font-weight: bold; color:white; height:50px ;text-align:
center">NewBay Store </td>
<td style="width: 200px">
</td>
</tr>
<tr style="font-size: 22px; background-color: lightblue; color: black">
<td colspan="3" style="height:50px">
@Html.ActionLink("Home", "Index", "NewBayHome") |
@Html.ActionLink("About", "About", "NewBayHome")
</td>
</tr>
<tr style="font-size: 18px;">
@RenderBody()
</tr>
</table>
</div>
</body>
</html>
Now, you can create your nested layout page named _SubLayout by referring _ParentLayout, as shown in the
following code:
@{
Layout = "~/Views/Shared/_ParentLayout.cshtml";
}
<table>
<tr>
<td style="background-color: lightblue; color: black; height: 350px; width: 200px;
vertical-align: top">
</td>
<td style="vertical-align: top;">
@RenderBody()
</td>
</tr>
</table>
In the preceding layout page code, the _ParentLayout.cshtml file is referred by using the Layout directive. In
addition, the markup to create the left side bar is added and the @RenderBody() method is called to render the
main content of the view.
Once you have created a nested layout, you can use the nested layout to define the structure of a view. To
accomplish this task, you can use the following code snippet:
@{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_SubLayout.cshtml";
}
Welcome to NewBay store
The preceding code snippet refers to the _SubLayout.cshtml file by using the Layout directive. The call to the
_SubLayout.cshtml file, in turn, calls the _ParentLayout.cshtml file.
In case, the parent layout of a nested layout renders a section, you will need to define additional
markup in your nested page to define and render the contents of the section. For example, suppose the parent
layout defines a section named featured and the target view provides the content for this section in a section
named featuredcontent. In this case, you need to include the following markup in your nested layout page:
@section featured{
@RenderSection("featuredcontent", required:false)
}
The @section directive defines the content for the featured section that is required by the parent layout.
@RenderSection() method renders the content of the featuredcontent section that is defined in the target
view.
Activity 7.2: Implementing a Nested Layouts
Styling Views
The look and feel of a view depends upon the appearance and arrangement of the HTML elements contained in
it. Therefore, you need to format the contents of a view to make it look attractive. Formatting each HTML helper
individually is a tedious task. In addition, it fails to bring consistency in the appearance of all the views on the
Web application. Styles provide a solution to this problem by enabling a programmer to apply consistent
formatting across the entire Web application. Styles are used to define a set of formatting options, which can be
reused to format different HTML helpers on a single view or on multiple views.
Let us see how to use styles for applying a consistent look and feel across various views in a Web application.
You can define the styles to be used in an MVC application in a .css file.
h1
{
font-weight: bold;
font-size: large;
color: green;
font-family: Arial;
}
The preceding styles will be applied to all the <h1> tags in any Web page that references the style sheet,
main.css. In the preceding style definition, h1 is the CSS selector that specifies the elements on which the style
needs to be applied.
Now, consider the following code snippet in a CSS file to display the content inside the H1 elements in red, and
the text inside the <H2> element as italic:
H1 {color:red;}
H2 {font-style: italic;}
In the preceding code snippet, H1 and H2 are the CSS selectors.
If you want to set the same attributes for more than one element, you can combine selectors as a single group.
For example, to display the text of both the H1 and H2 elements in red, you can type the following code snippet
in a CSS file:
You have seen how you can use the element name as the CSS selector for styling a Web page. Apart from using
an element name, you can also use other types of CSS selectors. Some of these are:
ID selector: CSS styles can be applied to an element with a specific ID using the ID selector. The ID
selector is used to identify an element that you need to style differently from the rest of the page. Each
element on a Web page can have a unique ID. An ID selector consists of a hash symbol ( #) followed by
the element ID.
Consider the following code snippet that specifies an id for the <p> tag:
<p id="pname">Barbie doll</p>
Now, consider the following code snippet to define the style specifications to be applied to the element,
whose ID is pname :
#pname
{
color:green;
font-size:20pt;
font-weight:bold;
}
The preceding code snippet selects the element with the id, pname , and styles it as per the specified
attribute values.
Class selector: The class selector is used to specify styles for a group of elements. Unlike an id
selector, a class selector is used more often when there is a need to apply a style on several elements in
a view. For example, suppose you have added three paragraphs on a Web page. Now, you want to
specify same formatting for the first two paragraphs and different formatting for the third paragraph.
You can accomplish this task by using the class selector. Unlike unique ids, multiple elements can
belong to the same class. Hence, you can set a particular style for multiple elements with the same class.
The class selector uses the HTML class attribute and is preceded with ".". Consider the following
markup:
<P class="red">This paragraph will appear in red color</P>
<P class="red">This paragraph will appear in red color</P>
<P class="green">This paragraph will appear in green color</P>
Now, consider the following code snippet to style the first and second paragraphs of the Web page:
.red
{
color:red;
}
.green
{
color:green;
}
In the preceding code snippet, the text color of the first two paragraphs will be red, and that of the third
paragraph will be green.
Further, consider the following code snippet to specify that only specific HTML elements should be
affected by a class:
p.center {text-align:center;}
p.left {text-align:left;}
In the preceding code, all the <P> elements with the class, center, will be center-aligned, and all <P>
elements with the class, left , will be left aligned. The other <P> elements, which are used without any
class inside a document, will not be affected. Similarly, all other types of elements with the class,
center or left , will not be affected.
Universal selector: The universal selector is used to select and specify styles for all the elements in a
particular area on the Web page or the whole Web page. The universal selector is defined by using the *
symbol. For example, to specify styles for all the elements inside the <div> tag on the Web page, you
can use the universal selector. Consider the following code snippet that specifies the <div> tag
containing some elements:
<div class="products">
<p id="product1">Mobile</p>
<p id="product2">Laptop</p>
</div>
You can apply styles to all the elements in the preceding <div> tag by using the universal selector, as
shown in the following code snippet:
div.products *
{
color:pink;
}
Importing Styles in an MVC Application
Once created, the .css file needs to be linked with HTML documents on which the styles are to be implemented.
This can be done by using the <link> tag.
The <link> tag is intended to link together the Web page with the style sheet. It is added to the <head> tag of the
Web page. For example, consider the following code snippet:
Now-a-days, Web applications can be accessed from a variety of devices, such as tabs, laptops, or mobile
phones having different page widths and browser capabilities. Because the size of the screen in different devices
may vary, the page width and the visual appearance of the Web application may change accordingly. This can
hamper the functionality of the website and the user’s experience.
By implementing adaptive rendering, the MVC model allows you to handle such a situation. Adaptive rendering
not only refers to automatically scaling down the page, but also to redrawing the page according to a device
screen. This enables the creation of an adaptive user interface.
For example, you must have seen a website on a desktop that displays a navigation bar as a horizontal list
containing links. However, when you visit the same website on a mobile device, the navigation bar is rendered
vertically to present the same functionality on a smaller device. This is possible by using adaptive rendering. For
example, consider the following figure that depicts adaptive rendering:
The preceding figure depicts how a Web page adapts its look and feel as per the available screen size.
To implement adaptive rendering and creating an adaptive user interface, the following features are used:
However, if you want to control the size and scaling of the Web page, you can use the viewport <meta> tag in the
head section of the view.
You can control the size of the viewport by using the viewport <meta> tag, as shown in the following code
snippet:
However, a better practice is to set the width of the viewport to the native screen size of the browser by using the
device-width keyword. This helps you to create the content that you can adjust according to the device
specifications. For example, consider the following code snippet:
For designing the preceding Web page, you have used the following markup:
<html>
<head>
<title>AAAA</title>
<link href="~/content/main.css" rel="stylesheet" type="text/css" />
</head>
@{
ViewBag.Title = "Index";
Layout = null;
}
<body>
<div id="container">
<div id="article1">
<h1> Acid Rain</h1> The term acid rain refers to what scientists call acid
deposition. It is caused by airborne acidic pollutants and has highly destructive
results.
Scientists first discovered acid rain in 1852, when the English chemist Robert Agnus
invented the term. From then until now, acid rain has been an issue of intense
debate among scientists and policy makers.
Acid rain, one of the most important environmental problems of all, cannot be seen.
The invisible gases that cause acid rain usually come from automobiles or coal-
burning power plants.
Acid rain moves easily, affecting locations far beyond those that let out the
pollution. As a result, this global pollution issue causes great debates between
countries that fight over polluting each other’s environments.
</div>
<div id="article2">
<h1>Air Pollution</h1> Every day, the average person inhales about 20,000 liters
of air. Every time we breathe, we risk inhaling dangerous chemicals that have found
their way into the air.
Air pollution includes all contaminants found in the atmosphere. These dangerous
substances can be either in the form of gases or particles.
The sources of air pollution are both natural and human-based. As one might expect,
humans have been producing increasing amounts of pollution as time has progressed,
and they now account for the majority of pollutants released into the air.
The effects of air pollution are diverse and numerous. Air pollution can have
serious consequences for the health of human beings, and also severely affects
natural ecosystems.
</div>
</div>
</body>
</html>
The preceding markup uses the main.css file, which contains the following code:
#container {
float: left;
width: 800px;
}
#article1 {
float: left;
width: 400px;
background: pink;
}
#article2 {
float: right;
width: 400px;
background: lightblue;
}
When you view the preceding Web page, the output is displayed correctly. However, when you reduce the
dimensions of the window, the look and feel of the Web page is hampered. Here, the Web page is displayed, as
shown in the following figure.
A Web Page After Reducing Dimiensions
In such a case, you can use media queries to add styles for reduced dimensions in the css file, as shown in the
following code snippet:
In addition to max-width , the following table describes some more properties that can be used with a media
query.
Properties Description
Web developers use browser detection techniques to ensure that the websites display properly when viewed with
specific browsers. To detect the capabilities of a browser in an MVC Web application, the
HttpBrowserCapabilities object is used, which provides the information about the browser during an HTTP
request. The information includes the type and level of support the browser offers. To expose this information,
the HttpBrowserCapabilities object uses strongly typed properties and a generic name-value dictionary. Some
properties of the HttpBrowserCapabilities object are:
Properties Description
The capabilities of a browser are determined through the Browser property of the ASP.NET intrinsic Request
object.
{
ViewBag.Message = "Please upgrade your browser";
}
The preceding code snippet uses the Browser property of the ASP.NET intrinsic Request object and checks
whether the browser is IE and the version is below 7. If yes, the message, Please upgrade your browser, is
rendered on the view by using the ViewBag object.
At times, modifying only css to manage the look and feel of a view according to the device is not sufficient.
Here, you need to create views specific for the device. ASP.NET MVC enables you to globally override views
for mobile devices. Upon receiving a request from a mobile browser, an ASP.NET MVC application first looks
for views with the naming convention of [view].mobile.cshtml . If a view matches the naming convention,
ASP.NET MVC renders it, as shown in the following figure.
Otherwise, the standard view ( [view].cshtml ) is rendered, as shown in the following figure.
The Standard View
MVC automatically renders the mobile specific view when it receives a request from a mobile browser.
However, now-a-days, a large number of mobile platforms are available in the market. These mobile platforms
use their own browsers. Therefore, a Web page that appears properly on one mobile platform may appear
differently on another platform. To solve this problem and render platform-specific views, you can define display
modes.
You need to define display modes in the Application_Start() method of the Global.asax file. For example,
consider that your Web application includes a layout that is specific to a browser for an Android mobile. In this
situation, you can create browser-specific views for that browser. However, before creating browser-specific
views, you need to create a new display mode named Android and write the code for examining the UserAgent
string received from a browser along with a request. The UserAgent string helps in identifying the type of
browser. Consider the following code snippet:
A layout is a feature that enables you to specify a common site template to be used across the views of
a website.
As a convention, the name of the layout file is preceded by the underscore (_) character.
A layout file defines the visual components that are common across a set of views.
To render the unique content associated with a view in the layout, the following methods can be used:
The @RenderBody() method
The @RenderSection() method
The @RenderBody() method enables you to define a placeholder in the layout to insert the main content
of the view.
The @RenderSection() method in a layout enables you to render a section specified in the view.
The _Layout.cshtml file is a default layout file that is included as part of the ASP.NET MVC project,
which is created by using any template except the Empty template.
Layouts are used to standardize the look and feel of all the views on a website.
A nested layout page refers to a layout that is derived from a parent layout.
You can define the styles to be used in an MVC application in a .css file.
An ID selector consists of a hash symbol (#) followed by the element ID.
The class selector uses the HTML class attribute and is preceded with ".".
The universal selector is defined by using the * symbol.
The <link> tag is intended to link together the Web page with the style sheet.
To implement adaptive rendering and creating an adaptive user interface, the following two-browser
features are used:
The viewport meta tag
CSS media queries
The Web pages are rendered in a virtual window known as a viewport, which is usually wider than the
actual width of the mobile device.
CSS media squeries allow you to apply different styles in your application to support different browsers
and devices with different sizes.
To detect the capabilities of a browser in an MVC Web application, the HttpBrowserCapabilities
object is used, which provides the information about the browser during an HTTP request.
Chapter 8
Enhancing Web Applications Using JavaScript
The success of an application largely depends on how easily and effectively it allows a user to interact with it.
For an application to be successful, its interface should be responsive and easy-to-use. Such an interface can be
designed by adding JavaScript to a Web application. You can use various predefined JavaScript libraries, such as
jQuery, to make the application interactive.
The response time of an application is an important factor that impacts the user experience. You can speed up the
response time of an application by implementing partial page updates using Asynchronous JavaScript and XML
(AJAX).
This chapter provides an overview of how an application is made responsive using JavaScript. In addition, it
discusses how the partial page updates are implemented using AJAX.
Objectives
By using client-side scripts, the preceding functionalities can be implemented. The client-side scripts enable you
to develop dynamic Web pages that can respond to the user input without interacting with a Web server. This
helps in reducing the network traffic because interaction with a Web server is not required in providing a
dynamic response to the user interaction. This, in turn, helps in improving the response time of a Web application
because the processing happens at the client side and round-trips to the server are not required.
JavaScript is a client-side scripting language that allows you to develop dynamic, interactive, and rich Web
applications. JavaScript is an easy-to-learn scripting language. Therefore, programmers are able to quickly
incorporate JavaScript functionalities into a Web page. However, to develop a Web application that provides
quick user interactions using JavaScript, you need to write a good amount of code because the JavaScript
functions vary from browser to browser. Thus, to simplify the task of developing such Web applications with
fewer lines of code, JavaScript provides various libraries, such as jQuery and jQuery UI.
In the earlier days of Web application development, it was a common practice to include JavaScript code and
HTML inside the same file. It was even normal to put the JavaScript code inside an HTML element as the value
of an attribute. For example, the onclick event handler of a div element was represented in the markup, as
shown in the following code snippet:
Unobtrusive JavaScript is a general approach to implement JavaScript in Web pages. In this approach, the
JavaScript code is separated from the HTML markup. In an ASP.NET MVC application, the JavaScript code is
separated from the markup by storing the JavaScript code in a .js file in the Script folder of the root directory of
an application.
To refer to the .js file in a view, you need to use the <script> tag, as shown in the following code snippet:
In the preceding code snippet, the Url.Content() helper method has been used to convert a relative
URL to an absolute URL.
Keeping all scripts in a separately downloadable file can give your site a performance boost because the browser
can cache the script files locally. In addition, Unobtrusive JavaScript allows you to use a strategy known as
progressive enhancement for your site.
Progressive enhancement is a technique that allows you to deliver the content progressively. It uses a layered
approach to deliver the content that allows everyone to access the basic content and functionality of a view, while
providing an enhanced version of the view to users whose device or browser supports features, such as scripts
and style sheets.
The _Layout.cshtml file that is included with most ASP.NET MVC project templates includes a section named
scripts, which specifies the placeholder for the scripts in a view. Therefore, a view that needs to refer to a custom
script can include the <script> tag for the custom JavaScript file within the scripts section definition, as shown
in the following code snippet:
@section scripts
{
<script src= '@Url.Content("~/Scripts/Myscript.js")' type='text/javascript'></script>
}
A JavaScript library is a set of prewritten JavaScript code, which helps in developing a JavaScript-based
application easily.
In most default ASP.NET MVC project templates, such libraries are present in the Scripts folder, which is
present in the root directory of the application. One of the commonly used JavaScript libraries present in this
directory is the jQuery library. jQuery is a cross-browser JavaScript library that helps you easily perform various
tasks, such as DOM traversal, event handling, and animating elements. It provides an easy-to-use API that allows
you to quickly provide complex functionality by writing very little code. This API works across a variety of
browsers and eliminates the need to write different versions of code for different browsers.
Apart from the jQuery library, the Scripts folder also contains jQuery plugins, such as jQuery UI and jQuery
Validation. These plugins add additional capabilities to the core jQuery library. Additional plug-ins such as
jQuery Mobile can also be downloaded and used in an application.
jQuery UI is an organised set of user interface interactions, effects, widgets, and themes built on top of the
jQuery JavaScript library. Thus, you can build highly interactive Web applications using jQuery UI.
jQuery validation makes the client-side form validation trivial. It is bundled with a set of validation methods,
such as email and URL validation that helps you to easily implement client-side validation.
jQuery Mobile is the mobile version of the jQuery library. It helps you to develop applications for mobile
devices.
In addition to the .js files for jQuery and its plugins, the Scripts folder contains several other files, as shown in
the following figure.
In the preceding figure, you will find the files containing min in their name. These files are the minified versions
of their corresponding script files. Minification is the process of removing unnecessary characters, such as white
spaces, new lines, and comments from the JavaScript code, without changing the functionality provided by the
code. Minified files are smaller in size as compared to their corresponding script files. This helps reduce the
amount of data to be transferred over the Internet.
Further, the Scripts folder contains some files containing vsdoc in their name. These files are annotated to help
Visual Studio provide better intellisense. The Scripts folder also contains some files that include the word,
unobtrusive, in their names. These files are written by Microsoft. These files integrate with jQuery and the MVC
framework to provide the unobtrusive JavaScript features. Further, the Scripts folder contains a JavaScript file
containing modernizr in its name. This file helps you take benefit of the evolving Web technologies, such as
HTML 5 and CSS3, and still have control over the older Web browsers that do not support these technologies. In
addition, the Scripts folder contains some files that include the word, knockout, in their names. These files
provide the data binding capabilities.
Using jQuery
jQuery helps in finding, traversing, and manipulating HTML elements inside an HTML document. In addition, it
helps you to animate HTML elements, handle events, and make your applications rich and interactive.
You can make use of the jQuery library present in the Scripts folder of the Web application, in a view by using
the <script> tag in the head section of the view. The following syntax is used to include a jQuery library in a
view:
The script tag instructs the browser that the HTML document uses a script.
The type tag specifies the type of scripting used.
The src tag specifies the name of the jQuery library used.
@Url.Content() is a helper method that converts a relative URL to an absolute URL.
The default _Layout.cshtml file that is included with most ASP.NET MVC project templates already includes a
reference to the jQuery library. Therefore, in such cases, you do not need to explicitly add a reference to the
jQuery library.
The execution of the jQuery code should occur only after the Web page has been fully loaded. To ensure that a
Web page is fully loaded before the jQuery code is executed on it, jQuery provides the document.ready()
function. Within this function, you can write the jQuery code to be executed on the HTML elements, after the
Web page has been fully loaded in the browser.
$(document).ready(function()
{
// jQuery code...
});
In the preceding syntax, the dollar sign ($) represents the start of a jQuery code block. The (document).ready()
function is useful for checking the readiness of the actions performed on an HTML element. For example, if the
jQuery code for hiding an image executes before the document is ready, it will lead to failure as the image that
the code is trying to hide has not yet rendered on the Web page.
Therefore, any code that needs to be executed after a page loads must be written inside the (document).ready()
function.
To add the customized client-side functionality to your website, you can write custom JavaScript/jQuery code in
a .js file and add it to the Scripts folder contained in the application’s root directory.
Now, to invoke the code written in your .js file from your application, you will need to refer to this file by using
the <script> tag, as given in the following code syntax:
jQuery can be used to select and manipulate HTML elements. It can also be used to handle events related to
HTML elements and apply effects to HTML elements. Let us see how to perform these operations with jQuery.
$(selector).action()
In the preceding syntax,
Consider a scenario where you want to hide the h1 elements on a mouse-click. For this, you can use the
following code snippet:
$(document).ready(function(){$("h1").click(function()
{$(this).hide();});});
In the preceding code snippet, all the h1 elements are selected and an anonymous function is assigned to click
event of every h1 element. Within the anonymous function, the h1 element, which is clicked by a user, is selected
by using the this keyword and its hide() method is called to hide the element.
In the preceding code snippet, the <h1> elements are referred to by the name, h1. However, HTML elements can
also be selected using a class or id. For example, an HTML element with the id, name , can be selected by using
the following syntax:
$("#name")
Similary, HTML elements with the class, myclass, can be selected by using the following syntax:
$(".myclass")
The jQuery library provides predefined functions to perform modifications on the content of the HTML elements.
The following table lists some of the functions used to modify the content of HTML elements.
<html>
<head>
<script type= "text/javascript" src="@Url.Content("~/Scripts/jQuery-1.7.1.js")">
</script>
<script src= "@Url.Content("~/Scripts/Myscript.js")" type="text/javascript"></script>
</head>
<body>
<h3>Complete the sentence</h3>
<p id="para">is a javascript library that enables the content to be appended after
the inner content in the selected element using the</p><br>
<button id="b">Click here to view the answer.</button>
</body>
</html>
Now, consider the script file, Myscript.js, containing the following code:
$(document).ready(function(){
$("#b").click(function(){
$("#b").html("You are viewing the answer");
$("#para").prepend(" <b>jQuery </b>");
$("#para").append(" <b>append() function</b>.");
});
});
In the preceding code, when a user clicks the Click here to view the answer button, the text on the button is
changed to, You are viewing the answer. This is done by using the html() function in the jQuery click event
handler for the button. In addition, the text,JjQuery, is added before the content in the <p> tag that has the id,
para , by using the prepend() function. Similarly, the content, append() function, is added after the content in
the <p> tag by using the append() function. Before the button, Click here to view the answer, is clicked, the
Web page appears, as shown in the following figure.
After the button, Click here to view the answer, is clicked, the Web page appears, as shown in the following
figure.
Handling Events
In jQuery, events are handled by using functions or predefined event methods. An event method is used to detect
an event and trigger a function when that event occurs. You can also handle events for manipuling HTML
elements.
The following table lists some of the event methods provided by jQuery.
<html>
<head>
<script type= "text/javascript" src="@Url.Content("~/Scripts/jQuery-1.7.1.js")">
</script>
<script src= "@Url.Content("~/Scripts/Myscript.js")" type="text/javascript"></script>
</head>
<body>
<h1>I am the header</h1>
<hr/>
<input type="button" id="change_header" value='Change the header'/></body>
</html>
Now, consider the script file, Myscript.js, containing the following code:
$(document).ready(function(){
$("#change_header").click(function(){
$("h1").html("I am the new header"); });
});
In the preceding code,JjQuery recognizes a click event when the user clicks the Change the header button. After
the event is recognized by jQuery, the function associated with the click event of the button is executed and the
text inside the <h1> element is changed.
Adding Effects
With the help of jQuery, amazing visual effects can be applied to the elements of a Web document. These visual
effects help enrich the browsing experience of a user. Some of the predefined jQuery effects that can be used to
add visual appeal to a Web page are:
Hide effect
Show effect
Toggle effect
Fade effect
Hide Effect
The hide() function is used to make an element disappear when an event, such as click or double-click, occurs.
$(selector).hide(speed)
In the preceding syntax, speed is an optional parameter that denotes speed at which an element disappears. The
values that can be used for the speed attribute are:
slow
fast
Duration in milliseconds
While specifying the speed attribute as duration in milliseconds, the value must not be enclosed within quotes.
However, while specifying the speed as slow or fast, the value must be enclosed within quotes.
Show Effect
The show() function is used to make a hidden element visible when an event occurs. The following syntax is
used to show the selected elements if they are already hidden:
$(selector).show(speed)
In the preceding syntax, speed is an optional parameter used to specify the speed with which the hidden element
reappears. The values that this parameter can take are slow, fast, and duration in milliseconds.
$(document).ready(function(){
$(".view").click(function(){
$("h3").show(2000);
});
$(".conceal").click(function(){
$("h3").hide();
});
});
In the preceding code snippet, the <h3> tag gets hidden in the browser window when the Click to hide button
is clicked. When the Click to view button is clicked, the <h3> tag is shown again in 2000 milliseconds.
Toggle Effect
The toggle() function can be used to switch between the show effect and the hide effect of an element. This
event can be used to hide or show the element alternatively when an event occurs.
$(selector).toggle(speed)
In the preceding syntax, speed is an optional parameter. It is used to specify the speed at which the selected
element appears and disappears. The values that this parameter can take are slow, fast, and duration in
milliseconds.
<html>
<head>
<script type= "text/javascript" src="@Url.Content("~/Scripts/jQuery-1.7.1.js")">
</script>
<script src= "@Url.Content("~/Scripts/Myscript.js")" type="text/javascript"></script>
</head>
<body>
<h3> This is some text.</h3>
<hr/>
<button class="view">Show/Hide</button>
</body>
</html>
Now, consider the script file, Myscript.js, containing the following code:
$(document).ready(function(){
$(".view").click(function(){
$("h3").toggle("fast");
});
});
In the preceding code snippet, the toggle() function hides and shows the <h3> element alternately.
Fade Effect
The jQuery fade effect is used to gradually reduce the opacity of the selected elements. There are various fade
functions, such as fadeOut() and fadeIn() , which can be applied on the selected elements.
The following table lists these functions to produce the fade effect.
<html>
<head>
<script type= "text/javascript" src="@Url.Content("~/Scripts/jQuery-1.7.1.js")">
</script>
<script src= "@Url.Content("~/Scripts/Myscript.js")" type="text/javascript"></script>
</head>
<body>
<p>CLICK HERE TO FADE ME AWAY!</p>
<br />
<button>Restore</button>
</body>
</html>
Now, consider the script file, Myscript.js, containing the following code:
$(document).ready(function () {
$("p").click(function () {
$(this).fadeOut(1200);
});
$("button").click(function () {
$("p").fadeIn(1200);
});
});
In the preceding code, the <p> tag is referred using its name. In the click event handler of the <p> tag, the
keyword, this , refers to the current HTML element, which is the <p> tag. When the user clicks the text, CLICK
HERE TO FADE ME AWAY!, the text fades away. When the Restore button is clicked, the text, CLICK HERE
TO FADE ME AWAY!, reappears.
The values that can be used for the speed attribute are:
slow
fast
Duration in milliseconds
While specifying the speed attribute as duration in milliseconds, the value must not be enclosed within quotes.
Using jQuery UI
jQuery UI library provides a set of widgets, such as date pickers, spinners, dialog boxes, and autocomplete text
boxes, which allow you to design a user interface and apply various effects to the UI elements. In addition, it
allows you to apply themes to the widgets to integrate their colors and styles with the website.
To use the jQuery UI library in a view, you need to include a reference to the jQuery UI script file in your view,
as given in the following code snippet:
Add/Remove/Toggle classes
Effect
Show/Hide/Toggle
Add/Remove/Toggle Classes
Using this technique, you can add, remove, or toggle class(es) for the HTML elements while applying the style
animations on them. Consider the following markup for a view:
<html>
<head>
<link rel="stylesheet" href="@Url.Content("~/Content/main.css")">
<script type= "text/javascript" src="@Url.Content("~/Scripts/jQuery-1.7.1.js")">
</script>
<script type= "text/javascript" src="@Url.Content("~/Scripts/jQuery-ui-1.8.20.js")">
</script>
<script src= "@Url.Content("~/Scripts/Myscript.js")" type="text/javascript"></script>
</head>
<body>
<div id="div1"></div>
<button id="button1">Add Class</button>
<button id="button2">Remove Class</button>
<button id="button3">Toggle Class</button>
</body>
</html>
The preceding markup generates a view consisting of a div element and three buttons titled Add Class , Remove
Class ,and Toggle Class . The view uses a stylesheet named main.css .
main.css
Now, consider the following style definitions included in the file:
div {
width:300px;
height: 200px;
background-color:yellow;
}
.myclass {
width : 600px;
height: 400px;
background-color:green;
}
In addition, the markup refers to a JavaScript file named Myscript.js. The Myscript.js file includes the following
code:
$(document).ready(function () {
$("#button1").click(function() {
$("#div1").addClass("myclass", 1000);
});
$("#button2").click(function () {
$("#div1").removeClass("myclass", 1000);
});
$("#button3").click(function () {
$("#div1").toggleClass("myclass", 1000);
});
});
When a user clicks the button titled, Add Class , the myclass class defined in the main.css file is applied to the
div element. Similarly, when a user clicks the button titled, Remove Class , the myclass class applied to the div
element is removed. When the user clicks the button titled, Toggle Class , the myclass class is applied to the
div element if it is not already applied. However, if the myclass class is already applied to the div element, the
class is removed from the div element.
If your view uses the default _Layout.cshtml layout included in most ASP.NET MVC project templates,
you need to add the script elements within the scripts section, as shown in the following code snippet:
@section scripts{
<script type= "text/javascript" src="@Url.Content("~/Scripts/jQuery-1.7.1.js")">
</script>
<script type= "text/javascript" src="@Url.Content("~/Scripts/jQuery-ui-
1.8.20.js")"> </script>
<script src= "@Url.Content("~/Scripts/Myscript.js")"
type="text/javascript"></script> }
Effect
Using this technique, you can apply various animation effects to an element, such as appear, bounce, blind, clip,
and fade. Consider the following markup for a view:
<html>
<head>
<script type= "text/javascript" src="@Url.Content("~/Scripts/jQuery-1.7.1.js")">
</script>
<script type= "text/javascript" src="@Url.Content("~/Scripts/jQuery-ui-1.8.20.js")">
</script>
<script src= "@Url.Content("~/Scripts/Myscript.js")" type="text/javascript"></script>
</head>
<body>
<div id="div1" style="width:300px; height: 200px; background-color:yellow;"></div>
<button id="button1">Apply Blind Effect</button>
</body>
</html>
The preceding markup generates a view containing a div element and a button titled, Apply Blind Effect. The
preceding view refers to a script file, Myscript.js, which contains the following code:
$(document).ready(function () {
$("#button1").click(function () {
$("#div1").effect("blind", 1000);
});
});
When a user clicks the button titled, Apply Blind Effect, the div element disappears in 1000 milliseconds with
a blind effect. Similarly, you can apply other effects, such as bounce and clip, to various HTML elements. For
example, you can use the following code to apply the bounce effect to a div element with the id, div1:
$("#div1").effect("bounce", 1000);
To apply the clip effect to a div element with the id, div1, you can use the following code:
$("#div1").effect("clip", 1000);
Show/Hide/Toggle
Using this technique, you can display or hide elements using custom jQuery effects. Consider the following
markup for a view:
<html>
<head>
<script type= "text/javascript" src="@Url.Content("~/Scripts/jQuery-1.7.1.js")">
</script>
<script type= "text/javascript" src="@Url.Content("~/Scripts/jQuery-ui-1.8.20.js")">
</script>
<script src= "@Url.Content("~/Scripts/Myscript.js")" type="text/javascript"></script>
</head>
<body>
<div id="div1" style="width:300px; height: 200px; background-color:yellow;"></div>
<button id="button1">Hide</button>
<button id="button2">Show</button>
</body>
</html>
The preceding markup generates a view consisting of a div element and two buttons titled, Hide and Show . The
markup refers to a custom script file, Myscript.js, which contains the following code:
$(document).ready(function () {
$("#button1").click(function () {
$("#div1").hide("blind", 1000);
});
$("#button2").click(function () {
$("#div1").show("clip", 1000);
});});
When the user clicks the Hide button, the div element hides with a blind effect. When the user clicks the Show
button, the div element appears with a clip effect.
Autocomplete
Datepicker
Accordion
Autocomplete
The Autocomplete widget adds an autocomplete text box to a Web page. This widget provides suggestions while
you type into the text box. Consider the following markup for a view:
<html>
<head>
<script type= "text/javascript" src="@Url.Content("~/Scripts/jQuery-1.7.1.js")">
</script>
<script type= "text/javascript" src="@Url.Content("~/Scripts/jQuery-ui-1.8.20.js")">
</script>
<script src= "@Url.Content("~/Scripts/Myscript.js")" type="text/javascript"></script>
<link rel="stylesheet"
href="http://code.jQuery.com/ui/1.10.3/themes/smoothness/jQuery-ui.css" />
</head>
<body>
<div>
<label for="country">Country: </label>
<input id="country" />
</div>
</body>
</html>
The preceding markup generates a view consisting of a div tag, which contains a label and an input field with
the id, country. The markup refers to a style sheet named jQuery-ui.css that defines styles to display jQuery UI
widgets. In addition, it refers to a custom script file named Myscript.js, which contains the following code:
$(document).ready(function () {
var countries = [
"Alaska",
"Argentina",
"Bahrain",
"Bhutan",
"Canada",
"China",
"Denmark",
"Egypt",
"France",
"Germany",
"Greece",
"Hong Kong",
"India",
"Japan",
"Mexico",
"New Zealand",
"Singapore",
"United Kingdom",
"United States"
];
$("#country").autocomplete({source: countries});
});
The preceding code snippet declares an array named countries , which defines the suggestions for the
autocomplete widget. It then calls the autocomplete() function to convert the input element with the id,
country , into an Autocomplete widget. While invoking this function, it passes the countries array as the source
for the Autocomplete widget. As the user types in the autocomplete widget, matching country names are shown
to the user in the form of suggestions, as shown in the following figure.
The Autocomplete Widget Showing Suggestions
Datepicker
The Datepicker widget allows a user to select a date from a calendar. Consider the following markup for a view:
<html>
<head>
<script type= "text/javascript" src="@Url.Content("~/Scripts/jQuery-1.7.1.js")">
</script>
<script type= "text/javascript" src="@Url.Content("~/Scripts/jQuery-ui-
1.8.20.js")"></script>
<script src= "@Url.Content("~/Scripts/Myscript.js")" type="text/javascript"></script>
<link rel="stylesheet"
href="http://code.jQuery.com/ui/1.10.3/themes/smoothness/jQuery-ui.css" />
</head>
<body>
<div>
<p>Date: <input type="text" id="datepicker" /></p>
</div>
</body>
</html>
The preceding markup creates a view that contains a text box with the id, datepicker . The preceding markup
refers to a custom script file, Myscript.js, which contains the following code to convert the text box into a
Datepicker widget:
$(document).ready(function () {
$("#datepicker").datepicker();
});
When the user clicks the text box, a Datepicker widget is displayed, as shown in the following figure.
The Datepicker Widget
Accordion
The Accordion widget displays collapsible content panels for presenting information in a limited amount of
space. For example, you can expand/collapse content broken into logical sections. To use accordion, you need to
include a reference to the jQuery UI css file, as shown in the following markup:
<link rel="stylesheet"
href="http://code.jQuery.com/ui/1.10.3/themes/smoothness/jQuery-ui.css" />
Consider the following markup for a view named Accordion.cshtml:
<html>
<head>
<link rel="stylesheet"
href="http://code.jQuery.com/ui/1.10.3/themes/smoothness/jQuery-ui.css" />
<script type= "text/javascript" src="@Url.Content("~/Scripts/jQuery-1.7.1.js")">
</script>
<script type= "text/javascript" src="@Url.Content("~/Scripts/jQuery-ui-1.8.20.js")">
</script>
<script src= "@Url.Content("~/Scripts/Myscript.js")" type="text/javascript"></script>
</head>
<body>
<div id="div1">
<h3>Team 1</h3>
<div>
<ul>
<li>Tom</li>
<li>Nancy</li>
<li>Harry</li>
<li>Sally</li>
</ul>
</div>
<h3>Team 2</h3>
<div>
<ul>
<li>Jim</li>
<li>John</li>
<li>Steven</li>
<li>Susan</li>
</ul>
</div>
<h3>Team 3</h3>
<div>
<ul>
<li>Mark</li>
<li>Ben</li>
<li>Kelly</li>
<li>Jane</li>
</ul>
</div>
<h3>Team 4</h3>
<div>
<ul>
<li>George</li>
<li>Lina</li>
<li>Amanda</li>
<li>Ken</li>
</ul>
</div>
</div>
</body>
</html>
The preceding markup generates a view, as shown in the following figure.
The Accordion.cshtml View
Now, to display the data of the various teams under different tab-like structures, you need to convert the div tag
with the id, div1 , into an accordion. For this, you need to add the following code in a script file associated with
the view:
$(document).ready(function () {
$("#div1").accordion();
});
Once the preceding code in a script file is associated with the view, the Accordion.cshtml view appears, as
shown in the following figure:
The Accordion.cshtml View After Adding the Accordion
In the preceding view, a user can click any of the section headers to view the details of that section.
You have seen how to include the script files for JavaScript libraries, such as jQuery and jQuery UI, in your
application. Although it is perfectly acceptable to serve jQuery scripts from your own server, a better approach is
to use a <script> tag that references jQuery from a Content Delivery Network (CDN).
The contents of the CDN are cached on servers located around the world. This helps improve the download speed
of the scripts at the client end. In addition, a number of sites may refer to jQuery from the same CDN. If a user
visits a website that refers to jQuery from a particular CDN, the script can be cached locally on the client. Now,
if the user visits another website that refers to jQuery from the same CDN, the cached script will be used, thereby
improving the performance and saving the cost of downloading scripts.
There are various CDN providers, such as Google and Microsoft, which provide free CDNs for a number of
JavaScript libraries.
To use a JavaScript library from a CDN, you need to provide the URL of the CDN as the value of the src
attribute of the <script> tag, as shown in the following code snippet:
<script src="https://ajax.googleapis.com/ajax/libs/jQuery/1.8.3/jQuery.min.js">
< /script>
Consider the example of a Web application that contains a Registration page. This page contains the drop-down
lists for selecting the country and the state in the selected country. When a user selects a country from the drop-
down list, the states for the selected country need to be populated in the state drop-down list. For this, a request
is sent to the server along with all the data contained in the Web page. The server processes the request, retrieves
the names of states in the selected country, and sends the entire Web page back to the client machine. This
process is called a postback.
This approach leads to the following drawbacks:
The user interaction with the application is interrupted every time a postback is made.
The user has to wait during each postback.
The full page is rendered and transferred to the client after each postback, which is time-consuming and
traffic intensive.
To overcome such drawbacks, a technology called AJAX can be implemented in Web applications. By
implementing AJAX in Web applications, the interaction between the client and the server becomes
asynchronous. This allows the users to interact with the Web application while waiting for a response from the
server. AJAX implementation enables partial updates in Web applications. This means that instead of loading the
entire Web page again, only the portion that needs to be updated is reloaded.
AJAX is a Web development technique used to create dynamic and interactive applications. It enables Web
applications to retrieve data from the server, asynchronously in the background, without interfering with the
display and behavior of the existing page. AJAX-enabled Web applications provide various advantages, such as:
Quick response to a user’s request: This is due to a partial-page updates feature that refreshes only
those parts of a Web page that have changed or updated. In addition, the partial-page updates feature
enables an application to use less bandwidth because only those parts of a Web page that have changed
or updated are sent to the server.
Asynchronous communication: It allows a user to interact with the rest of the Web page while the
application is processing the changed or updated parts of the Web page.
Web browser support: AJAX is supported by all the widely used Web browsers, such as Microsoft
Internet Explorer, Mozilla Firefox, and Apple Safari.
AJAX provides asynchronous communication to the server and partial updates of the Web pages. Therefore, it
can be used in the Web applications where a portion of the Web page needs to be updated, instead of updating
the entire page. For example, the weather forecasting websites need to be updated frequently to provide the
current temperature and weather updates. Therefore, AJAX can be used in these websites.
Let us learn how to use AJAX for making your websites responsive.
You have seen how to use HTML helpers to create forms and links that point to controller actions. In the same
way, there is a set of AJAX helpers, such as Ajax.ActionLink() and Ajax.BeginForm(), supported by
ASP.NET MVC. These AJAX helpers behave asynchronously and create forms and links that point to controller
actions. To work with such helpers, you need to use the jQuery.unobtrusive-ajax script. Ajax helpers depend
on unobtrusive MVC extensions for jQuery. Therefore, before using Ajax, you need to prepare your project for
Unobtrusive Ajax.
To use unobtrusive AJAX in an application, you need to update the Web.config file in the root folder of the
application. For this, you need to set the UnobtrusiveJavaScriptEnabled property in the Web.config file to
true .
The highlighted portion of the following code snippet illustrates how to enable the unobtrusive AJAX feature in
the Web.config file:
...
<configuration>
<appSettings>
<add key="webpages:Version" value="2.0.0.0" />
<add key="webpages:Enabled" value="false" />
<add key="PreserveLoginUrl" value="true" />
<add key="ClientValidationEnabled" value="true" />
<add key="UnobtrusiveJavaScriptEnabled" value="true" />
</appSettings>
</configuration>
...
In addition, you need to add references to the jQuery JavaScript libraries that implement the unobtrusive AJAX
functionality. You can refer to the libraries from individual views. However, if you want to refer to the libraries
from all the views, then you can refer to it from the _Layout.cshtml view using the <script> tag, as shown in
the following code snippet:
Consider a scenario where you want to add a link, Best Deal, on the Home page of the Newbay Store. You want
that when a user clicks this link, the details of the best deal should be retrieved from the server and displayed on
the Home page. However, this should happen through a partial page update, and the entire page should not be
posted back to the server. To implement this functionality, you can add the following markup in the view
corresponding to the Home page:
<div id=“msg”>
@Ajax.ActionLink(“Click here to see best deal for today!”,
“BestDeal”,
new AjaxOptions{
UpdateTargetId=“BestDeal”,
InsertionMode=InsertionMode.Replace,
HttpMethod=“GET”
})
</div>
<div id=“BestDeal”></div>
In the preceding markup, the first parameter to the ActionLink method specifies the link text, and the second
parameter is the name of the action you want to invoke asynchronously. The AjaxOptions parameter specifies
how to send the request, and what would be its effect. The UpdateTargetId property specifies that the response
of the Ajax request should be displayed in the element with the id, BestDeal . The InsertionMode property
specifies that the content of the target element will be replaced with the contents of the Ajax response. The
HttpMethod property specifies that the asynchronous request should be sent to the server by using the HTTP Get
method.
To handle the request at the server, you need to create the BestDeal action method in the appropriate controller,
as shown in the following code snippet:
@model MvcApplication1.Models.Product
<p>
Product:
@Model.name <br />
Price:
@Model.price
</p>
In the preceding markup, MvcApplication1 is the name of the application. This markup renders the details of the
product passed to it by the controller.
Once the user clicks the Ajax link, an asynchronous request is sent to the BestDeal action method. Once the
action returns a partial view, the script renders the partial view in the existing BestDeal element on the home
page.
Consider the scenario of the Home page of the Newbay store. You want to give the user the ability to search for
a product. As the user types in the search criteria, the details of the matching records should be retrieved from the
server and displayed on the same page, without having to post the page back to the server. This can be easily
implemented by sending an Ajax request to the server. To implement this functionality, you must place an
asynchronous form element on the Home page, as shown in the following code snippet:
@using (Ajax.BeginForm("Search", "Home",
new AjaxOptions
{
InsertionMode = InsertionMode.Replace,
HttpMethod = "GET",
OnFailure = "searchFailed",
LoadingElementId = "ajax-loader",
UpdateTargetId = "searchresults",
}))
{
<input type="text" name="q" />
<input type="submit" value="search" />
<img id="ajax-loader" src="@Url.Content("~/Content/Images/ajax-loader.gif")"
style="display:none"/>
}
<div id="searchresults"></div>
The preceding code snippet renders a textbox and button element on the screen. In addition, its adds a div
element with the id, searchresults , to the page. The first parameter of the Ajax.BeginForm() method specifies
the action method that will handle the Ajax request on the server. The second parameter specifies the controller
that contains the action method. The third parameter specifies various options for the Ajax request. In the
preceding code snippet, the third parameter specifies that:
The contents of the Ajax response should replace the existing content of the target element.
The HTTP method, Get, should be used for sending the request to the server.
If the Ajax request fails, the searchfailed() function should be executed.
While the asynchronous request is in progress, animated gif specified by the element id, ajax-loader
should be displayed to indicate progress.
The response from the server should be displayed in an element with the id, searchresults .
When the user clicks the submit button, the browser sends an asynchronous GET request to the Search action of
the Home controller. The Search action method can be defined, as shown in the following code snippet:
The _searchresults partial view contains the following markup to render the details of the products that match
the search criteria:
@model IEnumerable<MvcApplication1.Models.Product>
<table>
<tr>
<th>
@Html.DisplayNameFor(model → model.name)
</th>
<th>
@Html.DisplayNameFor(model => model.price)
</th>
<th> </th>
</tr>
@foreach (var item in Model) {
<tr>
<td>
@Html.DisplayFor(modelItem => item.name)
</td>
<td>
@Html.DisplayFor(modelItem => item.price)
</td>
</tr>
}
</table>
In the preceding markup, MvcApplication1 is the name of the application.
If the Ajax request fails, a function named searchFailed is invoked. The searchFailed() function is defined in
a custom JavaScript file referenced by the view, as shown in the following code snippet:
function searchFailed() {
$("#searchresults").html("Sorry, there was a problem with the search.");
}
Activity 8.2: Implementing Partial Page Updates Using AJAX
Summary
In this chapter, you learned that:
JavaScript is a client-side scripting language that allows you to develop dynamic and interactive rich
Web applications.
Unobtrusive JavaScript is a general approach to implement JavaScript in Web pages.
A JavaScript library is a set of prewritten JavaScript code, which helps in developing a JavaScript-
based application easily.
jQuery helps in finding, traversing, and manipulating HTML elements inside an HTML document.
With the help of jQuery, amazing visual effects can be applied to the elements of a Web document.
Some of the predefined jQuery effects that can be used to add visual appeal to a Web page are:
Hide effect
Show effect
Toggle effect
Fade effect
jQuery UI library provides a set of widgets, such as date pickers, spinners, dialog boxes, and
autocomplete text boxes, which allow you to design a user interface and apply various effects to the UI
elements.
You can add various effects to the various UI elements in your application. Some ways to implement
these effects in an application are:
Add/Remove/Toggle classes
Effect
Show/Hide/Toggle
You can easily add different types of widgets to your pages by using jQuery UI. Some widgets provided
by jQuery UI are:
Autocomplete
Datepicker
Accordion
A CDN is a network of servers containing shared code libraries.
AJAX is a Web development technique used to create dynamic and interactive applications.
AJAX-enabled Web applications provide various advantages, such as:
Quick response to a user’s request
Asynchronous communication
Web browser support
Chapter 9
Managing State and Optimizing Performance
An ASP.NET MVC application uses the HTTP protocol to communicate between a Web browser and a Web
server. HTTP is a stateless protocol and cannot automatically indicate whether the sequential requests are coming
from the same or different clients. Therefore, each time a Web page is posted to the server, a new instance of the
Web page is created. As a result, there is a loss of information associated with the page and the controls placed
on it. To overcome this limitation, ASP.NET MVC provides the various state management features.
A Web application must provide quick response to its users. Response time is a direct measure of the
performance of a Web application. ASP.NET MVC provides the various optimization techniques to enhance the
performance of a Web application.
This chapter discusses the various state management options provided by ASP.NET MVC. In addition, it
discusses the various techniques to enhance the performance of a Web application, such as caching, bundling,
and minification.
Objectives
Consider the example of the Newbay Web application where a customer needs to place an order online. While
doing this, the customer selects a product category from a drop-down list on the Web page. As soon as the
customer selects the category, a request is sent to the server to retrieve a list of product names belonging to the
selected category, which needs to be populated in another drop-down list on the same Web page. However, as
HTTP is a stateless protocol, when the request is sent to the server, a new instance of the Web page is created,
and therefore, all the information previously entered on the Web page is lost. This problem can be solved by
using state management.
Cookies
QueryString
TempData
Application State
Session State
Cookies
Cookies are small pieces of information that are stored on the client’s computer. The purpose of storing this
information is to offer a personalized experience to the user. For example, if a user has logged on to a website for
the first time, the name of the user can be stored in the form of a cookie. When a browser requests the same page
the next time, the website sends the cookie along with the requested information. The Web server reads the
cookie and extracts its value. It then processes the Web page according to the information contained in the cookie
and renders it on the Web browser.
For example, if the name of the user is stored in a cookie, the user’s name will be sent to the server along with
the request for a Web page. The name of the user can then be displayed with a greeting message on the Web
page when it is rendered on the browser.
Types of Cookies
Cookies can be either temporary or persistent. Temporary cookies exist in the memory space of a browser. When
the browser is closed, all temporary cookies added to the browser are lost. Temporary cookies are also known as
session cookies.
A temporary cookie is useful for storing information required for only a short time. Temporary cookies are also
useful for storing information that should not be written to the disk on a client computer for security reasons. For
example, a temporary cookie can be created to store the user’s login state. This cookie is sent with every
subsequent request to the same website to establish the user’s login credentials. This enables the user to login just
once during a session, and then access the various pages of the website without logging in again. However, when
the user closes the browser or logs out, the user’s session ends, and the cookie is removed. This is done as a
security measure to prevent a user from remaining logged in unintentionally.
A persistent cookie is saved as a text file in the file system of the client computer. Persistent cookies are used
when you want to store information for a longer time period. For example, persistent cookies can be used to store
customized user settings for a website. This helps in customizing the website when the user revisits the website.
While creating a persistent cookie, you can set the expiration date of the cookie, which defines the duration for
which the cookie will be stored on the client computer. If you do not set the expiration date of a cookie, the
cookie is maintained as a temporary cookie, as a part of the user’s session information. Once the user session is
finished, the cookie is discarded.
Creating Cookies
Persistent cookies can be created, as shown in the following example:
Response.Cookies["userInfo"]["userName"] = "Peter";
Response.Cookies["userInfo"]["lastVisited"] = DateTime.Now.ToString();
Response.Cookies["userInfo"].Expires = DateTime.Now.AddDays(2);
In the preceding example, the cookie, userInfo , with two subkeys, userName and lastVisited, is created.
Accessing Cookies
You can access the value of a cookie by using the Request built-in object. However, if you want to modify a
cookie, you need to use the Response built-in object of ASP.NET.
The following code snippet reads a cookie that stores a single value:
if (Request.Cookies["userName"].Value != null)
{
string Name = Request.Cookies["userName"].Value;
}
In the preceding code snippet, if the value of the cookie, userName, is not null, the value is assigned to the
string , Name.
Similarly, you can read the values from a cookie that stores multiple values. The following example reads a
cookie that stores multiple values:
if (Request.Cookies["userInfo"] != null)
{
string Name = Request.Cookies["userInfo"]["userName"];
string VisitedOn = Request.Cookies["userInfo"]["lastVisited"];
}
In the preceding code snippet, if the value of the cookie, userInfo , is not null, the value of the subkeys,
userName and lastVisited, are assigned to the strings, Name and VisitedOn , respectively .
A cookie is stored on the client computer and can be read by the server after a request for a page is
posted. Therefore, there is no server resource involved in maintaining the cookie.
A cookie is a text-based data structure that contains key-value pairs. Therefore, it is easy to create and
manipulate cookies.
A cookie can expire when the browser session ends or can exist for a specified time on the client
computer, as per your requirement.
Query String
Sometimes, it is required to transfer information from one page to another. For example, on the Newbay
shopping website, the product details page displays the list of categories of products. When the user selects a
category, another page with the detailed information about the selected category is displayed. This process
requires you to transfer the information about the selected category to another page so that the relevant details can
be displayed. You can perform this task by using a query string.
A query string provides a simple way to pass information from one page to another. It is the part of a URL that
appears after the Question mark ( ?) character. Consider the following URL that passes information by using a
query string:
http://www.Newbay.com/search?Category=Electronics
In the preceding URL, the query string defines the variable, Category , which contains the string, Electronics.
You can pass data from one page to another page in the form of a query string by using the Response.Redirect
method, as shown in the following statement:
Instead of using the preceding statement, the Contact() action method can also accept the query string as a
parameter, as shown in the following code snippet:
In the preceding statement, the strings, Electronics and Affordable , are stored in the variables, Category and
Description, respectively. The information stored in these variables can be retrieved by using the following code
snippet:
A query string is contained in the HTTP request for a specific URL. Therefore, there is no server
resource involved in storing a query string.
All browsers support query strings.
The information in a query string is directly visible to the users in the browser window. Therefore,
query strings are not useful for storing sensitive data.
Some browsers impose a limit of 2083 characters on the URL length. This restricts the amount of
information that you can pass from one page to another by using query strings.
TempData
TempData is a dictionary for storing temporary data in the form of key-value pairs. It can be used to store values
between one request and another. Values can be added to TempData by adding them to the TempData collection.
This information is preserved for a single request only and is designed to maintain data across a Web page
redirect. Any data stored in TempData will be available during the current and subsequent requests only, or until
the item is removed explicitly. This is useful in a situation when you want to pass data to a view during a Web
page redirect.
Now, consider the following code included in the view associated with the About() action method:
Its life is short and it lives only until the time the target view is fully loaded.
It can be used to store only one time messages, such as error messages and validation messages.
Application State
ASP.NET provides application state as a means of storing application-specific information. The information in
the application state is stored as key-value pairs.
Application state is created the first time a user accesses any URL resource in an application. After the
application state is created, the application-specific information is stored in it. The information stored in the
application state is shared among all the pages and user sessions of the Web application by using the
HttpApplicationState class. The HttpApplicationState class is accessed by using the Application property
of the HttpContext object.
Application state variables are global for an ASP.NET application. However, the values stored in the
application state variables are accessible only from the code running within the context of the originating
application. Other applications running on the system cannot access or modify the values.
Application State and Application Events
The application state is generally initialized and manipulated on the occurrence of certain application events.
These application events are:
Application.Start : This event is raised when the application receives the first request for a Web
page. It is also raised on the next request after the server, Web service, or website has been restarted.
The event handler for this event usually contains code for initializing the application variables.
Application.End : This event is raised when the server, Web service, or website is stopped or restarted.
The event handler for this event usually contains code to clean up the resources that the application has
used.
Application.Error : This event is raised when an unhandled error occurs.
The handlers for the preceding events are defined in the Global.asax file. The code to manipulate the application
state can be written inside these event handlers.
HttpContext.Application.Remove("MyVariable");
You can also remove all the application state variables and objects by using the following statement:
HttpContext.Application.RemoveAll();
Once added, an object remains in the application state until the application is shut down, the Global.asax file is
modified, or the item is explicitly removed from the application state.
Each browser’s request for a Web page initiates a new thread on the Web server.
Calling the Lock() method on an Application object causes ASP.NET to block attempts by the code running on
other worker threads to access anything in the application state. These threads are unblocked only when the
thread that called the Lock() method calls the corresponding Unlock() method on the Application object.
Consider the following code snippet that locks and unlocks the variable, PageCounter:
HttpContext.Application.Lock();
if (HttpContext.Application["PageCounter"] == null)
{
HttpContext.Application["PageCounter"]=1;
}
else
{
HttpContext.Application["PageCounter"]=(int) HttpContext.Application["PageCounter"
]+1;
}
HttpContext.Application.UnLock();
In the preceding code snippet, the Lock() method is called before accessing the value of the PageCounter
variable. This ensures that the variable cannot be modified simultaneously by any other thread. After calling the
Lock() method, the value of the PageCounter variable is modified. Once modified, the UnLock() method is
called to release the imposed lock on the PageCounter application state variable. Then, the variable can be
modified by other threads.
The Lock() method locks all the items in the application state object. In other words, you cannot
selectively lock items in the application state.
Advantages and Disadvantages of Application State
The application state has the following advantages:
The application state is easy to use and consistent with other .NET Framework classes.
Storing information in the application state involves maintaining only a single copy of the information.
The data stored in the application state is lost when the Web server containing the application state fails
due to server crash, upgrade, or shutdown.
The application state requires server memory and can affect the performance of the server and the
scalability of the Web application, if it occupies excess memory space.
You can implement the application state to increase the performance of the Web application. For example,
storing relatively static data that is required across pages/sessions in the application state can enhance the
performance of the Web application by reducing the overall number of data requests to a database server.
However, it is important to remember that application state variables, which contain large blocks of information,
can reduce the Web server performance as the server load increases. In addition, the memory occupied by a
variable stored in the application state is not released until the value is explicitly removed or replaced. Therefore,
it is preferred to use the application state variables with small and less frequently-changed data.
Session State
In ASP.NET, session state is used to store session-specific information for a Web application. Unlike application
state, the scope of session state is limited to the current browser session. If multiple users are accessing a Web
application, each user will have a different session state. If a user exits from a Web application and returns later,
the user will have a different session state.
Session state is structured as a key-value pair for storing session-specific information that needs to be maintained
between server round trips and requests for pages.
The session state has a built-in support in ASP.NET. The built-in session state feature automatically performs the
following actions:
Identify and classify requests coming from a browser into a logical session on the server.
Store session-specific data on the server.
Raise session lifetime-related events, such as Session.Start and Session.End, which can be handled
in the Global.asax file.
Automatically release session data if a browser does not access an application within a specified timeout
period.
When a user first requests a page from an ASP.NET website, the website automatically adds a session cookie to
the client browser to store the current session ID. This cookie is sent to the server along with all the subsequent
requests within the session.
Identifying a Session
Each active ASP.NET session is identified and tracked by a unique session ID string containing American
Standard Code for Information Interchange (ASCII) characters. The session ID strings are communicated across
client/server requests by using either an HTTP cookie or a modified URL containing the embedded session ID
string. The SessionStateModule class is responsible for generating or obtaining session ID strings.
Similar to the application state, you can store objects and variables in the session state. By default, a session
variable is active for 20 minutes without any user interaction. In an ASP.NET Web application, the objects stored
in the session state are stored on the server.
Session["MyVariable"]="HELLO";
You can retrieve the value of the variable, MyVariable , by using the following statement:
You need to consider the following issues when adding variables and objects to the session state:
Any variable or object that you add to the session state is available until the user closes the browser
window. The variables and objects are automatically removed from the session state if the user does not
request a page for more than 20 minutes, which is the default duration for session timeout.
Any variable or object added to the session state is related to a particular user. For example, you can
store different values for MyVariable for two different users accessing the Web page, and users can
access only the value that is assigned to the copy of the session variable associated with them.
Session state is global to the entire application for the current user. Session state is not lost if the user revisits a
Web page or visits a different page by using the same browser window. However, session state can be lost in the
following ways:
Similar to application state, you can remove an object or a variable added to the session state by using the
Remove() method or the RemoveAll() method based on the requirement.
Session.Start : This event is raised when a user requests the first page from a website and is useful for
initializing session variables.
Session.End: This event is raised when a user session expires or when the Session.Abandon() method
is called.
The handlers for the preceding events are defined in the Global.asax file. The code to initialize and manipulate
session state can be written inside these event handlers.
The following markup shows some important options that can be set for the <sessionState> element:
cookieless
timeout
mode
Value Description
The value for the timeout attribute should be set in such a way that it is short enough to allow the server to
reclaim valuable memory after a client stops using the application. At the same time, the value should be long
enough to allow a client to pause and continue a session without losing it.
The timeout attribute can also be set programmatically, as shown in the following statement:
Session.Timeout = 15;
Access of data is fast as it stores session data in a memory object of the current application domain.
It ensures platform scalability as it can work in a multiprocess configuration.
In addition to the state management techniques discussed here, there are various other techniques,
such as View State, Control State, and Hidden Fields. These techniques are supported by ASP.NET Web
forms applications and are not available in ASP.NET MVC applications.
To improve the overall performance of your Web application, you need reduce the number of server interactions
with the database. ASP.NET MVC provides the various techniques to optimize the performance of a Web
application. Caching is one of the techniques that can be used to optimize the performance of a Web application.
Caching reduces the number of server interactions with the database by storing the data in the cache memory for
a specific period of time.
You can also improve the performance of a Web application by reducing the number of requests and the size of
the requests between the client and the server. This can be done by techniques, such as bundling and
minification. In addition, you can adopt some best practices to further optimize the performance of a Web
application.
Consider the scenario of the Newbay application where you want the application to display the latest products
available with their prices on the Home page. For this, you need to retrieve the updated list of products from the
database so that your Web page always displays the current list of products with their prices.
In such a situation, where you frequently need to query the database for the updated list, the interaction with the
database becomes one of the most important factors that can affect the performance of an application. This is
because executing a query against a database takes a substantial amount of time. Moreover, the same data may
need to be fetched multiple times from the database, when the data is requested by multiple clients.
In such a situation, you can use the output caching technique to improve the performance of a Web application.
Output caching allows you to cache the content returned by a controller action. As a result, the same content does
not need to be generated each time the controller action is invoked.
Before implementing output caching, you need to consider the various factors, such as:
Identify whether output caching is relevant for your application. If the content of your application
changes frequently, output caching may not be useful.
Identify the duration for which the output must be cached. This would depend on how frequently data
associated with the output changes.
Identify the location where you need to cache the output. You can cache the output on locations, such as
client machines, the Web server, or both.
Caching is an important and extensively-used concept to enhance the application performance. The major
benefits of using caching are:
Reduced access time: When most of the requests are processed by the cache itself and need not be sent
to the database server, the access time of the Web page is reduced significantly.
Less bandwidth required: Caching can be implemented on the client computer or on the server. If
caching is implemented at the client computer, most of the requests and responses do not require data
transfer over the network between the client and the server. This, in turn, reduces the bandwidth
required for the communication. Implementing caching at the server side will also reduce the bandwidth
requirement as the data transfer between the server and the database would be reduced.
Lesser load on server: Caching avoids executing the same code repetitively to create the same result.
This reduces the CPU usage at the server, and in the process, lowers the load on the server.
Output caching improves the performance of an ASP.NET MVC application by enabling you to cache the pages
of the application for a specified duration. When the user requests the same page within the specified period of
time, instead of rerendering the page, ASP.NET MVC serves the cached page to the user.
In an ASP.NET MVC application, you can implement caching at the controller action level. You can apply the
output cache attribute to a controller action or the entire controller you decide to cache. By doing this, you can
cache the result returned from a controller action. This will result in getting the same content each and every time
a new user invokes the same action. The following code snippet shows how to enable caching by adding an
output cache attribute to a controller action.
You can avoid such a situation by caching the output for a specified duration. The duration for which a Web
page is cached will depend on the frequency at which the underlying data changes. If the data rarely changes, the
Web page can be cached for a long duration. However, if the data associated with the Web page changes too
frequently, caching the Web page for too long may result in serving stale data to the users.
Therefore, if the data associated with a particular Web page changes frequently and there are thousands of users
requesting the same page per second, you can cache the output for a couple of seconds. Caching the output for a
small duration of time is called micro caching. When the traffic on the Web application is high, micro caching
significantly reduces the number of queries to access the database.
So far, you have seen how to enable output caching by adding the [OutputCache] attribute either to an individual
controller action or to an entire controller class. However, you can specify the duration and location of the cache
attribute. In order to see the effect of the output caching, consider the following code snippet:
If you invoke the Index() action multiple times by entering URL/ Home/ Index in the address bar of your
browser and hitting the Refresh/ Reload button in your browser repeatedly, the time displayed by the Index view
would not change for 3 seconds. The same time is displayed because the view is cached. This view is cached for
everyone who visits your application. Anyone who invokes the Index() action will get the same cached version
of the Index view. This means that the amount of work that the Web server must perform to serve the Index view
is dramatically reduced.
In addition to the duration of the cache, you can also define the location where you want the data to be cached.
When you use the [OutputCache] attribute, content is cached at three locations: the Web server, any proxy
server, and the Web browser. However, you can set your own location by modifying the Location property of
the [OutputCache] attribute. The [OutputCache] attribute has the Location property that can be used to specify
the location of the output to be cached. The Location property can take the following values:
Any :The output cache can be located on the browser, a proxy server participating in the request, or the
server where the request was processed.
Client: The output cache is located on the browser where the request originated.
Downstream : The output cache can be stored in any HTTP cache-capable device other than the original
server, such as the proxy servers and the client that made the request.
Server: The output cache is located on the Web server where the request was processed.
None : The output cache is disabled for the requested page.
In an enterprise environment, client machines generally obtain access to the Internet through a proxy
server. A proxy server is a server that sits between a client application, such as a Web browser and the
Internet. When a client requests an online resource, the request is intercepted by the proxy server, and then
forwarded to the target Web server.
By default, the Location property has the value, Any . However, there are situations in which you might want to
cache content only on the browser or the server.
For example, if you are caching information that is personalized for each user, you should not cache the
information on the server. However, you might want to cache the personalized content in the browser cache to
improve performance. If you cache content in the browser, and a user invokes the same controller action multiple
times, the content can be retrieved from the browser cache instead of the server. In order to see the effect of
setting the Location property, consider the following code snippet:
To avoid such a situation, you can take advantage of the VaryByParam property of the [OutputCache] attribute.
This property enables you to create different cached versions of the same content. For example, consider the
Product() action method that returns a list of products, and the Details() action method that returns the details
for the selected product, as shown in the following code snippet:
[OutputCache(Duration=3600, VaryByParam="none")]
public ActionResult Product()
{
ViewData.Model = (from m in db.products select m).ToList();
return View();
}
[OutputCache(Duration=3600, VaryByParam ="id")]
public ActionResult Details (int id)
{
ViewData.Model = db.products.SingleOrDefault(m => m.Id == id);
return View();
}
}
}
In the preceding code snippet, the Product() action includes the VaryByParam property with the value, none .
The VaryByParam attribute specifies how many copies of the page need to be saved. In this example, the value of
the VaryByParam attribute is set to none , which indicates that only one copy of the page is to be cached. When
the Product() action is invoked, the same cached version of the Product view is returned. The Details() action
includes the VaryByParam property with the value, id. The SingleorDefault extension method returns the only
element of the sequence that satisfies a specified condition or a default value if no such element exists. When
different values of the id parameter are passed to the controller action, different cached versions of the Details
view are generated. In addition, you can set the VaryByParam property to the following values:
*:Create a different cached version whenever a form or query string parameter varies.
None : Never create different cached versions.
Semicolon separated list of parameters : Create different cached versions whenever any of the
specified form or query string parameters in the list varies.
You can apply the cache profile to several controllers and controller actions and control how they cache
contents from one central location.
You can modify the Web.config file without recompiling the application.
For example, to create a cache profile, you need to include the following code snippet in the <system.web>
section of a Web configuration file:
<caching>
<outputCacheSettings>
<outputCacheProfiles>
<add name="Cache1Hour" duration="3600" varyByParam="none"/>
</outputCacheProfiles>
</outputCacheSettings>
</caching>
In the preceding code snippet, the Cache1Hour profile is applied to a controller action with the [OutputCache]
attribute. For example, in order to implement the Cache1Hour profile to the Index() action method of the Home
controller, consider the following code snippet:
Consider a scenario where the Product categories are retrieved from the database and shown as links on each and
every page of the Newbay Web application. Retrieving the product categories from the database and rendering
them on a view as links is a time-consuming activity. Moreover, this activity needs to be repeated for every page
in the Web application. Therefore, the code to retrieve the categories needs to be repeated in each and every
controller action in the Web application.
To avoid these problems, you can retrieve the categories just once and cache the resulting HTML by using donut
hole caching.
You can implement donut hole caching by making use of the child action methods provided by ASP.NET MVC.
A child action method is a controller action that is only meant to be invoked during the execution of other
controller actions. Child actions act as any other controller action and their output can be cached as well.
In order to implement donut hole caching, you need to create a Controller action and include the logic, as
shown in the following code snippet:
[ChildActionOnly]
[OutputCache(Duration=60)]
public ActionResult Categories()
{
var db = new ProductDBContext();
var Categories = db.Products.select(p=>p.Category).Distinct();
ViewBag.Categories = Categories.ToArray();
return PartialView();
}
In the preceding code snippet, the Distinct() method used in the LINQ query to retrieve category
details ensures that only distinct categories are retrieved.
In the preceding code snippet, the [ChildActionOnly] attribute creates a child action that returns the product
categories from the database. It then returns the partial view named Categories that contains the following
markup:
<ul id="navigation">
@foreach (string category in ViewBag.Categories)
{
<li> @Html.ActionLink(category, category, "Products")</li>
}
</ul>
You can then use the Html.Action() helper method in any view to tell ASP.NET MVC to execute the child
action method and render the partial view associated with it at a particular place within the view.
For example, consider the following code snippet written in a view which calls the child action method,
Categories() .
@Html.Action("Categories", "Home")
In the preceding code snippet, Home is the name of the controller that contains the child action method,
Categories . Including the Action() helper method in each view of your Web application will ensure that links
corresponding to all the product categories appear on all the views. In addition, as the [OutputCache] attribute
has been specified for the child action method, once the product categories are retrieved from the database and
the partial view has been generated, the HTML for the partial view will be cached and used for all the subsequent
requests to the website.
Most Web pages in a Web application typically contain dynamic data that needs to be retrieved from a database.
However, executing a database query each time a user places a request can slow down the performance of the
application. This problem can be solved by using a concept called data caching.
Data can be cached in an ASP.NET MVC application by using the MemoryCache class.
Consider the following code snippet that illustrates how to cache data in an application by using the MemoryCache
class:
The first parameter of the AddOrGetExisting() function specifies the unique identifier of the object that needs to
be stored in the memory cache. The second parameter specifies the object that needs to be stored in the cache,
and the third parameter specifies the time when the cache should expire.
The data cache may fetch the outdated content, which is stored in memory, instead of taking the latest from the
database. To overcome this problem, you can reduce the amount of time for storing data in the cache. This helps
in providing updated content to the users.
You can implement HTTP caching in the browser cache and the proxy cache. Storing data in the browser cache
helps remove the need to repeatedly download content from the server. Web browsers frequently check content
for updates. If the content is updated in the server, Web browsers download the content from the server to attend
to user requests. Otherwise, Web browsers render content from the local cache.
The functionality of the proxy cache is similar to the functionality of the browser cache. However, many users
can access the cache in a proxy server, while only one user can access the browser cache at a time.
Preventing Caching
Consider a Web application that involves frequent content updates. If you cache the output of such Web
applications, it will prevent the users from viewing the content updates. In order to overcome this problem, you
can implement an HTTP header called Cache-Control.
The Cache-Control header indicates to the Web browser how to handle the local cache or proxy server cache. All
HTTP clients, such as browsers and proxy servers, respond to the instructions provided in the Cache-Control
header to determine how to handle the local cache of a Web application.
You can use the HttpCachePolicy.SetCacheability() method to specify the value of the Cache-Control
header. To prevent caching in your Web application, you should set the value of the Cache-Control header to
NoCache , as shown in the following code snippet:
Response.Cache.SetCacheability(HttpCacheability.NoCache);
Activity 9.2: Optimizing Performance of a Web Application
Bundling and Minification are the two techniques provided by ASP.NET MVC, which improve the load time of a
Web page by reducing the number of requests to the server and the size of the requested resource, such as CSS or
JavaScript.
Bundling
Bundling is a technique that allows you to combine multiple files, such as CSS and JavaScript, into a single file.
Combining such files into a single file reduces the number of requests between the client and the server. Most
modern browsers restrict the number of open connections to any given hostname to six, which is independent of
the type of files getting downloaded. This means that while six requests are being processed, any additional
requests for resources on a host will need to wait until another request completes.
When there are a number of files, such as style sheets and scripts, which need to be downloaded, at times, a lot
of time is spent in waiting for a request to complete, while the actual download does not take much time. You
can solve this problem by using bundling. Bundling allows you to combine multiple files into a bundle that can
be downloaded as a single entity.
In order to implement bundling in a Web application, you must define your bundles or files that you would like to
combine together. In an ASP.NET MVC application, this happens in the BundleConfig class in the App_Start
folder. You need to create a bundle within the RegisterBundles() method present in the BundleConfig class, as
shown in the following code snippet:
Similarly, a new instance of the StyleBundle class has been created to create a bundle of styles. The virtual
path, ~/Content/css , has been assigned to the bundle. The Include() method is used on the bundle object to
specify the files that should be included in that bundle.
In order to include these bundled files in a view/layout, you can use the @Styles.Render and @Scripts.Render
methods in the view or layout file. Then, you need to provide the virtual path that you configured in the bundle
configuration as a parameter to these methods, as shown in the following code snippet:
@Scripts.Render("~/bundles/jqueryval")
@Styles.Render("~/Content/css")
Minification
Minification is a technique that helps in reducing the size of a file by removing unnecessary whitespaces and
comments, and shortening the variable names. Minified code is especially useful for interpreted languages, such
as JavaScript, which are deployed and transmitted over the Internet because it reduces the amount of data that
needs to be transferred.
By implementing minification, you can drastically reduce the size of a file, thereby reducing the time required to
get it from the server and load it into the browser.
While building an ASP.NET MVC application, there are different approaches which can be used to improve the
performance of the application. Some of the most commonly-used approaches are:
Avoid Redirects
Redirects help user to point to a new page from an old page. In addition, it guides the user to a correct page.
However, inserting a redirect slows down user experience. This is because each redirect creates an additional
HTTP request and, thus, increases the round-trip time.
When a Web browser sends a request to the server, it indicates the support for compression in its Accept-
Encoding header, as shown in the following example:
Accept-Encoding: gzip, deflate
If the Web server receives this header in the request, it can send a compressed HTTP response to the client. For
compressing the response, it can use one of the methods, such as gzip or deflate, as indicated by the client.
Summary
In this chapter, you learned that:
At times, you need to ensure that some or all the pages of a Web application should be accessible only to specific
users. In addition, the information on the Web application, which is intended for a specific user, should not be
visible to other users. Therefore, before a user can access the restricted Web pages, you need to verify the identity
of the user. You can accomplish this task by using a mechanism known as authentication.
Moreover, you need to verify the rights given to a user for accessing specific resources on the website. A Web
application accomplishes this task by using a mechanism known as authorization.
This chapter discusses how to implement authentication and authorization in a Web application.
Objectives
Implement authentication
Implement authorization
Implementing Authentication
Consider the scenario of the NewBay store website that allows users to view and buy products. On this website,
anybody can view the products. However, to buy a product, the user must be a member of the website. In this
case, a user who wishes to buy a product on the website needs to be verified. By using a mechanism known as
authentication, the identity of the user can be verified. Authentication is the process of identifying an individual,
usually based on the username and password provided by the user.
MVC allows you to implement authentication by using any of the following authentication modes:
Forms Authentication
Windows Authentication
OpenID/OAuth
Forms Authentication
While using forms authentication, the website itself is responsible for implementing authentication. Here, the
website can authenticate the users by providing a login form on the Web page, where the users can provide their
username and password, as shown in the following figure.
A Login Form
In the preceding figure, when the users click the login button, the authentication mechanism ensures that the users
have entered a valid username and password. Forms authentication uses a session cookie to authenticate user
requests.
In websites that use forms authentication, if a user tries to access a restricted page, such as a Member page,
ASP.NET redirects the user to the login page.
When you create an ASP.NET MVC application by using the Internet Application template, the MVC
application implements the forms authentication and provides the basic functionality that allows users to
authenticate themselves to the website. The Internet Application template uses the following statement between
the <system.web> and </system.web> tags in the Web.config file to configure forms authentication:
<authentication mode="Forms">
</authentication>
In the preceding <authentication> element, the attribute mode is set to Forms . This specifies that the
application uses forms authentication.
An application created using the Internet Application template allows the users to register and login to the
website and enables them to change their password. This functionality comes out of the box and the code to
implement this functionality is included in the Account controller and the corresponding views and models.
Forms authentication is the default authentication type enabled for MVC applications created using the Internet
Application template.
Windows Authentication
Windows authentication is typically used for intranet applications that run across a company’s firewall. In
Windows authentication, the users are allowed to use their standard Windows user name and password for
accessing the website. Once the users are logged on to the desktop, Window automatically authenticates them to
the application.
Visual Studio provides the Intranet Application template that implements Windows authentication. The
Intranet Application template uses the following statement between the <system.web> and </system.web> tags
in the Web.config file to configure Windows authentication:
When you run an application created by using the Intranet Application template, the Home page will be
displayed, as shown in the following figure.
In the preceding figure, the message, Hello MyPC\Peter!, refers to the Windows account name. This message is
displayed by using the following code in the layout:
The Windows account name displayed on the Home page will depend on the Windows account used for
logging on to the machine.
OpenID/OAuth
OAuth and OpenID are authorization protocols. They enable users to logon to a website by using the credentials
for third party authentication providers, such as Google, Twitter, Facebook, and Microsoft.
When you create an MVC application using the Internet Application template, the third party authentication
providers need to be configured in the App_Start\AuthConfig.cs file in the application folder. The
AuthConfig.cs file contains the commented code, as shown in the following code snippet:
When you run the application and view the login page, the login page will be displayed, as shown in the
following figure.
The Login Page
When you click the Google button shown in the preceding figure, the login page of the Google website is
displayed, which allows you to logon to the application.
Task 10.1: Using Windows Authentication
To ensure the security of a Web application, a user must be logged on to access specific URLs within the
application. This can be done by using the Authorize action filter. Action filters are attributes that let you add
behavior that can be executed either before an action method is called or after an action method is executed. The
Authorize attribute is the default authorization filter provided with ASP.NET MVC. You can use the Authorize
attribute to:
To ensure that only authenticated users are allowed to access the BuyProduct() action method, you need to add
the Authorize attribute on the BuyProduct() method, as shown in the following code snippet:
[Authorize]
public ActionResult BuyProduct()
{
return View();
}
Once you have added the Authorize attribute on the BuyProduct() action method, the access to the
corresponding view is restricted. Therefore, whenever any user tries to access this view, a page to authenticate
the user is displayed. To configure the page to be displayed for user authentication, the following code snippet is
used in the Web.config file:
<authentication mode="Forms">
<forms loginUrl="~/Account/Login" timeout="2880" />
</authentication>
In the preceding code snippet, the <authentication> element contains a <forms> element that specifies the login
URL for the application. Whenever a user tries to access a restricted resource, the user is redirected to the login
URL. The timeout attribute of the <forms> element specifies the amount of time in minutes, after which the
authentication cookie expires. It is set to 2880 minutes. Its default value is 30 minutes.
When a user is redirected to the login URL, the return URL is appended to the login URL in the form of a query
string. The return URL specifies the URL of the restricted page that the user tried to access when he/she was
redirected to the login page. When the user enters the valid details in the login form, the user is redirected to the
return URL.
Once the user is successfully logged in, an authentication cookie is set at the client’s end. The name of this
cookie is .ASPXAUTH. The browser sends this cookie along with every subsequent request. Therefore, the user
need not log in again. The .ASPXAUTH cookie exists until the user closes the browser. However, if the user
selects the Remember me checkbox on the Login page, then the cookie will persist between the browsing
sessions.
Securing a Controller
You have seen how to add the Authorize attribute to a specific action method within a controller. You can also
secure an entire controller by adding the Authorize attribute on the controller, as shown in the following code
snippet:
[Authorize]
public class ShoppingCartController : Controller
{
...
}
The preceding code snippet will authorize all the action methods defined in the ShoppingCartController
controller.
However, if you don’t want to secure certain action methods within the controller, you need to use the
AllowAnonymous attribute on those action methods, as shown in the following code snippet:
[AllowAnonymous]
public ActionResult Index()
{
return View();
}
In the preceding code snippet, the AllowAnonymous attribute on the Index() action method specifies that the
access to the Index() action method does not require authentication.
Introduction to Membership
An ASP.NET MVC 4 application created by using the Internet Application template provides some useful
features for implementing authentication and authorization. To provide these features, the application template
uses a membership provider called SimpleMembership.
When you create an MVC application by using the Internet Application template, the Visual Studio project
wizard automatically creates the Membership database with connectionstring specified in the web.config file.
The Membership API provided by the SimpleMemberShipProvider class can be used to populate the database
with the details of users and roles.
The SimpleMembershipProvider class works with the SQL server and handles membership tasks, such as
creating and deleting user accounts.
The Internet template defines certain components to bootstrap SimpleMembership. These include:
The \Models\AccountModels.cs file: This file defines a model for a basic user account. It includes the
definition of the UserProfile class that provides the details of a user to be stored in the membership
database. The UserProfile class is defined, as shown in the following code snippet:
public class UserProfile
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int UserId { get; set; }
public string UserName { get; set; }
}
The preceding code snippet defines the UserId and UserName properties of the UserProfile class. You
can modify the UserProfile class by adding more properties according to your requirement.
When you create an MVC application by using the Internet Application template, AccountController and the
corresponding views and models provide all the basic functionality to authenticate the user. The Internet
Application templateuses forms authentication to implement authentication. Forms authentication is
customizable. Therefore, you can change the AccountController class and corresponding views to manage the
look and feel of the login form. You can also customize the information to be stored in the database.
The AccountController controller uses the WebSecurity class that comes from the Microsoft library named
WebMatrix . The WebSecurity class provides security and authentication features. It includes the ability to
perform authentication tasks, such as create user accounts, log users in and out, and reset or change passwords.
The WebSecurity class, in turn, refers to the SimpleMemberShipProvider class, which is responsible for storing
the data in a database.
The AccountController class contains the Register() action method that returns the form for registration. In
addition, it contains the HttpPost version of the Register() action method, which creates the record in the
database, and is defined, as shown in the following code snippet:
[HttpPost]
public ActionResult Register(RegisterModel model)
{
if (ModelState.IsValid)
{
// Attempt to register the user
try
{
WebSecurity.CreateUserAndAccount(model.UserName, model.Password);
WebSecurity.Login(model.UserName, model.Password);
return RedirectToAction("Index", "Home");
}
catch (MembershipCreateUserException e)
{
ModelState.AddModelError("", ErrorCodeToString(e.StatusCode));
}
}
In the preceding code snippet, the CreateUserAndAccount() method creates a user record in the database.
Further, the Login() method logs the user on to the application.
The AccountController class also contains a Login() action method that returns the login form. The HttpPost
version of the Login() method is called when the user clicks the login button on the login form. The Login()
action method is defined, as shown in the following code snippet:
[HttpPost]
public ActionResult Login(LoginModel model, string returnUrl)
{
if (ModelState.IsValid && WebSecurity.Login(model.UserName, model.Password, persistCookie:
model.RememberMe))
{
return RedirectToLocal(returnUrl);
}
// If we got this far, something failed, redisplay form
ModelState.AddModelError("", "The user name or password provided is incorrect.");
return View(model);
}
In the preceding code snippet, the Login() action method accepts the username and password entered by the user
as the properties of the model object that it receives as a parameter. It also accepts the return URL as a parameter.
The return URL is the URL of a restricted page that the user tried to access when he/she was redirected to the
Login page. The preceding Login() action method checks whether the model state is valid and attempts to log on
to the site by using the WebSecurity.Login() method. If the login is successful, the user is redirected to the
return URL. Otherwise, an error is added to the model state.
You can access the current membership provider, such as SimpleMembershipProvider , by using the property
named Provider , as shown in the following code snippet:
Configuring Membership
To configure a Web application to use SimpleMembershipProvider , you need to add the following code snippet
between the <system.web> and </system.web> tags in the Web.config file:
<membership defaultProvider="SimpleMembershipProvider">
<providers>
<clear />
<add name="SimpleMembershipProvider"
type="WebMatrix.Webdata.SimpleMembershipProvider,WebMatrix.WebData"
/>
</providers>
</membership>
If you need to add custom logic for authentication in an application, you need to create your own custom
membership provider. For example, consider the following code snippet:
Once you have implemented the custom membership provider class, you need to override the ValidateUser()
method defined in the SimpleMembershipProvider class. Consider the following code snippet to override the
ValidateUser() method defined in SimpleMembershipProvider :
Then, you need to modify the Web.config file to apply the custom provider class to the application, as shown in
the following code snippet:
<membership defaultProvider="CustomMemberProvider">
<providers>
<clear/>
<add name="CustomMemberProvider" type="CustomAdminMembershipProvider"/>
</providers>
</membership>
Activity 10.1: Implementing Authentication
Implementing Authorization
Consider the scenario of the NewBay store website where only the administrator is allowed to add the product
details in a database. In this case, whenever another user tries to access the interface for adding the product
details, he/she should not be permitted to do so. For verifying the permissions given to an authenticated user for
accessing certain resources in a Web application, you need to implement authorization. Authorization is a
mechanism that determines the rights given to the users for accessing the available resources.
You can authorize specific users and roles by using the Authorize attribute. Consider the following code snippet
to authorize specific users:
[Authorize(Users="Smith, James")]
public class ManageStoreController:Controller
{
...
}
In the preceding code snippet, only the users named Smith and James are the authorized users to access the
ManageStore controller.
In addition, you can also assign roles to different users, and then implement authorization at the role level, as
shown in the following code snippet:
[Authorize(Roles="Administrator")]
public class ManageStoreController : Controller
{
...
}
The preceding code snippet will restrict the access of the ManageStore controller to users who belong to the
Administrator role.
The Roles parameter can also take more than one role, as shown in the following code snippet:
[Authorize(Roles="Administrator, SuperAdmin")]
public class ManageStoreController:Controller
{
...
}
You can also use a combination of roles and users, as shown in the following code snippet:
[Authorize(Roles="Manager", Users="Smith,James")]
public class ManageStoreController:Controller
{
...
}
The preceding code snippet allows the users Smith and James, and all users with the role, Manager to access the
ManageStore controller.
Roles help you to assign specific rights to users. ASP.NET MVC provides role providers to implement roles.
Some role providers provided by ASP.NET MVC are:
You can access the current role provider, such as SimpleRoleProvider , by using the property named Provider ,
as shown in the following code snippet:
Defining Roles
When you create an MVC application by using the Internet Application template, the Visual Studio project
wizard automatically creates the membership database with the connectionstring specified in the web.config
file.
You can populate this database with the required roles by seeding the membership database. For this, you can
add the following code in the Seed() method of the Configuration.cs file.
Once you have created a role in the database, you can add users to that role. For example, to assign the role,
Admin, to a user named Smith_Thompson, the following code snippet can be used:
if (!roles.GetRolesForUser("Smith_Thompson").Contains("admin"))
{
roles.AddUsersToRoles(new[] { "Smith_Thompson" }, new[] { "admin" });
}
In the preceding code snippet, if the role, admin , is not already assigned to a user named Smith_Thompson , the
AddUserstoRoles() method adds the role, admin , to the user that has the username, Smith_Thompson .
Once the roles and users are created in the database, you can use the Authorize attribute on the action method
that needs to be restricted. For example, consider the following action method that can only be accessed by a user
with the admin role:
[Authorize(Roles = "admin")]
public ActionResult AdminHome()
{
return View();
}
When any user tries to access the AdminHome page, the login page will be displayed where the user needs to
provide the valid credentials for a user with the admin role. If the user provides valid credentials, he/she can
access the AdminHome page.
When a user logs in, he/she should be shown only those links that are linked to resources that the user has rights
to access. For example, the AdminHome link should be visible only to the administrator. To prevent this link from
being displayed to other users, you can use the following code in the relevant view:
@if(User.IsInRole("admin"))
{
@Html.ActionLink("AdminHome","AdminHome")
}
The preceding code snippet displays the AdminHome link only when the user logs in with an account that has the
admin role.
Configuring Roles
To configure a Web application to use SimpleRoleProvider , you need to add the following code snippet
between the <system.web> and </system.web> tags in the Web.config file:
ASP.NET MVC also enables you to create custom role providers. By using custom role providers, you can
implement role management that uses your own database schema and logic. To build a custom role provider, you
need to create a class that inherits the RoleProvider class, as shown in the following code snippet:
Once you have implemented the GetRolesForUser() function, you need to apply the custom role provider to the
application by modifying the Web.config file, as shown in the following code snippet:
Summary
In this chapter, you learned that:
Authentication is the process of identifying an individual, usually based on the username and password
provided by the user.
MVC allows you to implement authentication by using any of the following authentication modes:
Forms Authentication
Windows Authentication
OpenID/OAuth
Forms authentication is the default authentication type enabled for MVC applications created using the
Internet Application template.
Windows authentication is typically used for intranet applications that run across a company’s firewall.
Action filters are attributes that let you add behavior that can be executed either before an action method
is called or after an action method is executed.
The Authorize attribute is the default authorization filter provided with ASP.NET MVC.
You can use the Authorize attribute to:
Secure a controller action.
Secure a controller.
Secure an entire application.
The SimpleMembershipProvider class works with the SQL server and handles membership tasks, such
as creating and deleting user accounts.
Some membership providers provided by ASP.NET MVC are:
ActiveDirectoryMembershipProvider
SqlMembershipProvider
SimpleMembershipProvider
UniversalProviders
Authorization is a mechanism that determines the rights given to the users for accessing the available
resources.
Roles help you to assign specific rights to users.
Some role providers provided by ASP.NET MVC are:
ActiveDirectoryRoleProvider
SqlRoleProvider
SimpleRoleProvider
UniversalProviders
Chapter 11
Deploying a Web Application
Once a Web application is developed, you need to make it accessible to the users over the Internet. In order to let
the users access the application through the Internet, you need to deploy it on a Web server.
This chapter explains how to prepare a Web application for deployment. In addition, it discusses how to host a
Web application on IIS.
Objectives
While developing a Web application by using Visual Studio, when you execute the application, the application is
automatically deployed on Internet Information Server (IIS) Express. IIS Express makes deployment simple
because it runs with our identity, and allows us to start and stop the Web server whenever required.
However, to make the Web application accessible over the Internet or an intranet, you need to host it on a full
version of IIS or any other Web server.
Before deploying a Web application on a Web server, you need to prepare the application for deployment. This
involves certain activities, such as:
During the development phase, a Web application is saved in a folder on the computer on which it is developed.
However, once the application is developed, it needs to be deployed on a Web server. When you deploy the
application on a Web server, such as IIS, you need to identify the files and folders to be copied to the destination
server.
By default, Visual Studio deploys only the files that are required to run the application. However, in some
scenarios, you might have special requirements. For example, some of the database files present in the App_Data
folder are only required while developing a Web application. In such a case, you can identify these database files
and exclude them at the time of deployment. For this, you need to configure the deployment settings in the
Project properties.
When an ASP.NET application is deployed on a Web server, there are some settings in the deployed
application’s Web.config file, which need to be different from the Web.config file in the development
environment. For example, you might want to disable debug options and change connection strings so that they
point to different databases. These groups of settings need to be set up in the Web.config transformation file.
A transformation file refers to an XML file that allows you to specify how the Web.config file should be
changed when it is deployed. The transformation actions can be specified in the Web.config file by using XML
attributes.
A transform file is associated with a build configuration. By default, Visual Studio creates the Debug and Release
build configurations by the names, Web.Debug.config and Web.Release.config . However, you can also create
custom build configurations.
The Web.release.config file stores the changes that Microsoft Visual Studio applies to the Web.config file,
when you compile the application in the Release mode.
The Web.debug.config file stores changes that Microsoft Visual Studio applies to the Web.config file, when you
compile the application in the Debug mode.
Before you publish the application by using the release configuration, you need to remove the debug attribute
from the <compilation> element in the Web.config file. For this, the following markup is included in the
Web.release.config file:
<system.web>
<compilation xdt:Transform=“RemoveAttributes(debug)” />
</system.web>
In the preceding markup, the xdt:Transform attribute is used to remove the debug attribute from the Web.config
file.
You can also add additional elements to the transformed Web.config file. For example, the following code
shows how to insert a new connection string setting in the transformed Web.config file.
<connectionStrings>
<add name=“DemoConnStr” connectionString=“Data
Source=|DataDirectory|demo.mdf“
providerName=“System.Data.SqlServerCe.4.0” xdt:Transform=“Insert”/>
</connectionStrings>
In the preceding code snippet, the value, Insert, has been used for the xdt:Transform attribute to insert a new
connection string in the transformed Web.config file.
Precompiling the Web Application
The most basic technique for deployment is to copy the application components to the hard drive of a Web
server. In this technique, the various application components are deployed to the Web server in the uncompiled
form. This type of deployment has the following issues:
These problems can be resolved by precompiling an application before deploying it to a Web server.
Precompiling a Web application involves compilation of the source code into DLL assemblies before
deployment. Precompiling a Web application provides the following advantages:
It provides faster response time because the Web application need not be compiled the first time it is
accessed.
It helps in identifying the bugs that can occur when a Web page is requested. These bugs are removed
at the time of compiling the Web application. Then, the compiled and error-free Web application is
deployed on to the server and is rendered to a user.
It hides and secures the source code of a Web application from malicious users.
Before you deploy a Web application, you need to make sure that it is running properly. The errors occurring
while the application is running need to be diagnosed and fixed. You also need to ensure that there are no
performance-related issues with your Web application. As a developer, you are focused on creating a Web
application that runs smoothly after its deployment. Once an application is deployed, you need to ensure that the
application is working properly and is not giving unexpected results. For this, you need to keep track of the
execution of your Web application. This will enable you to track any error or performance-related issue in your
application.
ASP.NET provides you with the tracing feature that enables you to track the program execution, thereby ensuring
that your Web application runs properly. You can use this feature to view the diagnostic information about a
particular Web page. This information includes the execution time of page methods, the time spent rendering
page controls, and the content of various collections, such as the query string, HTTP header, and session state.
In addition to the standard diagnostic information, tracing can also be used to display the custom tracing
information about the execution of an application. Tracing information can also be written to an event log or a
text file by using trace listeners.
After deploying a Web application, you, as a system administrator, need to constantly monitor it for its proper
functioning. Many unexpected problems, such as website experiencing heavy load, may occur while the
application is running in the real-world environment. By monitoring a Web application, you can detect the
problems occurring in the application and troubleshoot them.
IIS is a Web server that provides a comprehensive platform, which helps you develop, host, and manage Web
applications. IIS is proprietary of Microsoft and is packaged along with the Windows operating system. By
default, IIS is turned off when Windows is installed. Therefore, before deploying an application on IIS, you need
to configure IIS on the Windows operating system.
Instead of using a deployment package, you can directly deploy a website to a target server, such as:
For deploying a Web application on any of the preceding target servers, you can use the Publish Web wizard.
While using the Publish Web wizard, you need to perform the following tasks:
If you are deploying your Web application to Windows Azure or a target server owned by a service provider, the
service provider will provide you a .publishsettings file. You can automatically create the publish profile by
importing this .publishsettings file while using the Publish Web wizard.
Once you have selected a publish method, you need to specify the connection details of the target server.
In addition to specifying the build configuration, you can also specify the various file publish options such as:
Whether to remove files on the destination server that have no matching files in the Web application on
your development computer.
Whether to precompile the project before publishing.
Whether to prevent the files in the App_Data folder from being deployed on the target server.
Further, you need to specify the connection strings to the target database servers that your application needs to
use after deployment. In addition, you can specify whether to run code first migrations on application start.
To deploy a Web application on a Web server, you can create a deployment package. You can use the Publish
Web wizard to configure one or more publish profiles for creating a deployment package. A publish profile
represents the deployment options, such as the server on which you want to deploy a Web application and the
databases that are required to be deployed.
Once you have created a deployment package, you can install the package on the destination server by using the
<projectname>.deploy.cmd file that Visual Studio creates with the package.
Task 11.2: Creating a Deployment Package
Summary
In this chapter, you learned that:
While developing a Web application using Visual Studio, when you execute the application, the
application is automatically deployed on Internet Information Server (IIS) Express.
Before deploying a Web application on a Web server, you need to prepare the application for
deployment. This involves certain activities, such as:
Identifying the files and folders to be copied to the destination server
Configuring Web.config transformations
Precompiling the Web application
Testing the application in an environment similar to production
A transformation file refers to an XML file that allows you to specify how the Web.config file should
be changed when it is deployed.
IIS is a Web server that provides a comprehensive platform, which helps you develop, host, and manage
Web applications.
While using the Publish Web wizards, you need to perform the following tasks:
1. Create a publish profile
2. Configure the connection settings
3. Configure the publish and database settings
4. Publish the project
Glossary
B
Bundling
Bundling is a technique provided by ASP.NET MVC that allows you to combine multiple files, such as CSS and
JavaScript, into a single file.
Consists of the components of the application that control the flow of execution and communication between the
presentation and data layers.
C
Client-side scripting
Client-side scripting enables you to develop Web pages that can dynamically respond to user input without
having to interact with a Web server.
Controller
Refers to a set of classes that handle communication from the user and the overall application flow.
Cookies
Cookies are small pieces of information that are stored on the client’s computer.
D
Data layer
Consists of components that expose the application data stored in databases to the business logic layer
A Web page whose content is generated dynamically by a Web application or that responds to user input and
provides interactivity is called a dynamic Web page.
F
Fat client and thin server
The architecture in which the business logic layer resides on the client tier is referred to as the fat client and thin
server architecture. In this architecture, the client accepts user requests and processes these requests on its own.
Fat server and thin client
The architecture in which the business logic layer resides on the server is referred to as the fat server and thin
client architecture. In this architecture, the client accepts requests from the users and forwards the same to the
server.
J
JavaScript library
AJavaScript library is a set of prewritten JavaScript code, which helps in developing a JavaScript-based
application easily.
jQuery
jQuery is a cross-browser JavaScript library that helps you easily perform various tasks, such as DOM traversal,
event handling, and animating elements.
jQuery UI
jQuery UI is an organised set of user interface interactions, effects, widgets, and themes built on top of the
jQuery JavaScript library.
L
LINQ
LINQ offers a consistent programming model to query data from different data sources.
M
Model
Refers to a set of classes that describes the data that the application works with.
N
Nested layout
A nested layout page refers to a layout that is derived from a parent layout.
P
Presentation layer
Consists of the interface through which the users interact with the application.
R
Razor
Razor is a markup syntax that allows you to embed server-side code (written in C# or VB) in an HTML markup.
Routing
Routing is a feature that enables you to develop applications with comprehensible and searchable URLs.
S
Scaffolding
MVC provides a scaffolding feature that provides a quick way to generate the code for commonly used
operations in a standardized way.
Server-side scripting
Server-side scripting provides users dynamic content that is based on the information stored at a remote location,
such as a back-end database.
A Web page that contains only static content and is delivered to the user as it is stored is called a static Web
page.
U
Unobtrusive JavaScript
Unobtrusive JavaScript is a general approach to implement JavaScript in Web pages. In this approach, the
JavaScript code is separated from the HTML markup.
V
View
ViewBag
ViewBag is a dynamic object that allows passing data between a controller and a view.
ViewData