Professional Documents
Culture Documents
Model View Controller or MVC as it is popularly called, is a software design pattern for
developing web applications. A Model View Controller pattern is made up of the following
three parts:
Model - The lowest level of the pattern which is responsible for maintaining data.
View - This is responsible for displaying all or a portion of the data to the user.
Controller - Software Code that controls the interactions between the Model and
View.
MVC is popular as it isolates the application logic from the user interface layer and supports
separation of concerns. Here the Controller receives all requests for the application and then
works with the Model to prepare any data needed by the View. The View then uses the data
prepared by the Controller to generate a final presentable response. The MVC abstraction can
be graphically represented as follows.
The model
The model is responsible for managing the data of the application. It responds to the request
from the view and it also responds to instructions from the controller to update itself.
The view
The controller
The controller is responsible for responding to user input and perform interactions on the data
model objects. The controller receives the input, it validates the input and then performs the
business operation that modifies the state of the data model.
MVC stands for Model view controller. MVC is a framework which we used to build
applications in client side using Model, view and controller design. Here we will see what
is Model, view and controller?
Model
View
Controller
Every controller holds one or more than one action method(s). These action methods are
calling during the execution through URL like let’s say the URL is
localhost/Home/Index.
Here Home is the controller name and Index is the ActionMethod name. Now every
Action method has its own View by its name. So here a view will be stored within the
View à Home folder named Index.cshtml.
Whenever you will request for Home/Index the index.cshtml file will be shown within
that View à Home folder
Now let’s see how to start this. Open your Visual Studio 2012 it has inbuilt MVC 4.0 and
MVC 3.0. If you are using Visual studio 2010 then download the MVC 4.0 set up here
Choose 4.0 project and set your name like as shown below
The next thing you have to do to choose Razor as a View engine and don't forget to
choose an Empty template like as shown below
Now open your solution explorer in that we have three folders named Model, Controller
and View and it will contain two web.config in solution one in the root folder and
another one in the View folder. The root one is the normal one to deal and the second
file in View folder blocks the direct access of the View folder.
Normally Home is the default Controller and Index is the default action method. If
you open the RouteConfig.cs file in the App_Start folder you will come to see in the
method RegisterRoutes that is default controller and ActionMethod is Home and Index
respectively. If you want to change it you can do easily.
OK now let’s start with a simple program. Right click on the Controller folder and
choose Create new Controller. Name it HomeController.
Open the HomeController, there will be one Index ActionMethod. Now right click on
the Action Method name (Index) and you will see there are two options Add View and
Go to View. As you didn't create any View previously click on the Add View option. A
new window will be opened. Keep the name as it is, Set the View engine as Razor. Right
now we don't have any Master page so keep the Use a layout or master page blank.
Now click on the Add button and check in the View folder in Solutions Explorer. Within a
view folder there will be a folder named as your controller name Home. And within that
Home controller there is index.cshtml
Open index.cshtml page and place any html code under <h2>Index</h2> Or you can
delete it and put your code. Now hit the run button and your project will run with the all
html code in your index.cshtml.
As the default ones are running we would not see anything in the URL. It is showing
something like http://localhost:59244/.Put
http://localhost:59244/Home/Index instead of the URL right now. You will see the
same result as Home controller is running and Action Method Index is calling. And you
are viewing the content of index.cshtml.
Now it’s clear if you create another Action Method in the Home Controller. So let’s create
another one.
By default WCF takes care of creating SOAP messages according to service DataContracts
and OperationContracts. However some time you required full control on SOAP messages
structure and how serialization happens specially when your service needs to be interoperable
for consuming by different types of clients or service needs to provide extra layer of security
on messages and message parts. Messages are exchanged in different way of Message
Exchange Patterns in WCF .
Northwind system which is used for Order Entry web application with order details is
running on Windows server which might have effect on the Product inventory back office
application running on unix machine and payment application with customer details on
mainframe machine. At the same time Product details need to send to your marketing
campaign through API.
For accomplishing all those requirements you might create different DataContracts which
will give you the XML xsd for communication with clients and other services. Such XSDs
are tightly coupled which faces versioning issues and do not give you any control. For any
last minute change on serialized object you will have to use events like OnSerializing or
OnDeserializing. For example each of these operation requires to validate the private license
key. This validation needs to be done in OnSerializing and if validation is sucessful then
serilize the object.
You can also choose to create MessageContracts which will give you more control over the
SOAP and no need for handling any extra events. SOAP headers are the reasonable place to
keep the private keys like license key which can be use for validation.
Implementation of MessageContract
Create a new service using Create new WCF service library and test using
WCFTestClient
2. Customer DataContract
Add new Customer DataContract to handle the Customer related info by adding new
class to Service library. Add below code to the class and reference to
System.Runtime.Serialization
namespace NorthwindServices
{
[DataContract]
public class Customer
{
[DataMember]
public string CustomerName;
[DataMember]
public string PhoneNumber;
[DataMember]
public string Email;
}
}
3. Request MessageContract
Create a new MessageContract for request by adding new class to Service library.
Name it as CustomerContactRequest. Add reference to System.ServiceModel
namespace NorthwindServices
{
[MessageContract(IsWrapped=false)]
public class CustomerContactRequest
{
[MessageHeader]
public string LicenseKey;
[MessageBodyMember]
public int CustomerID;
}
}
4. Response MessageContract
namespace NorthwindServices
{
[MessageContract(IsWrapped = false)]
public class CustomerContactResponse
{
[MessageBodyMember]
public Customer Contact;
}
}
5. Add ServiceContract
[ServiceContract]
public class ICustomerService
{
[OperationContract]
[FaultContract(typeof(string)]
CustomerContactResponse
GetCustomerContact(CustomerContactRequest request);
}
6. Implementation of ICustomerService
public CustomerContactResponse
GetCustomerContact(CustomerContactRequest request)
{
if (request.LicenseKey != AppKey)
throw new FaultException<string>("Invalid Key");
<service name="NorthwindServices.CustomerService">
<host>
<baseAddresses>
<add baseAddress = "http://localhost:7741/NorthwindServices/
CustomerService" />
</baseAddresses>
</host>
<endpoint address ="" binding="wsHttpBinding"
contract="NorthwindServices.ICustomerService">
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding"
contract="IMetadataExchange"/>
</service>
8. Host CustomerService
9. CustomerService client
response.Contact = client.GetCustomerContact
("northwind-xxx-1234-abc", 1234);
Console.WriteLine(response.Contact.CustomerName);
Console.WriteLine(response.Contact.Email);
Console.WriteLine(response.Contact.PhoneNumber);
}
catch (FaultException<string> ex)
{
Console.WriteLine(ex.Detail);
}
Console.Read();
}
WebGrid in MVC
Model:
Person.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.Entity;
using System.ComponentModel.DataAnnotations;
namespace MVC_myfirst_Mvcapplication.Models
{
public class Person
{
public int ID { get; set; }
[Required]
[StringLength(30)]
public string First { get; set; }
[Required]
[StringLength(30)]
public string Last { get; set; }
public DateTime Birthdate { get; set; }
}
}
}
Controller :
PersonController.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using MVC_myfirst_Mvcapplication.Models;
namespace MVC_myfirst_Mvcapplication.Controllers
{
public class PersonController : Controller
{
PersonContext db = new PersonContext();
//
// GET: /Person/
//
// GET: /Person/Create
//
// POST: /Person/Create
[HttpPost]
public ActionResult Create(Person Person)
{
db.People.Add(Person);
db.SaveChanges();
return RedirectToAction("Index");
}
}
}
View:
Person >
Create.cshtml
@model MVC_myfirst_Mvcapplication.Models.Person
@{
ViewBag.Title = "Create";
}
<h2>Create</h2>
<script src="@Url.Content("~/Scripts/jquery.validate.min.js")"
type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")"
type="text/javascript"></script>
@using (Html.BeginForm()) {
@Html.ValidationSummary(true)
<fieldset>
<legend>Person</legend>
<div class="editor-label">
@Html.LabelFor(model => model.First)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.First)
@Html.ValidationMessageFor(model => model.First)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.Last)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Last)
@Html.ValidationMessageFor(model => model.Last)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.Birthdate)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Birthdate)
@Html.ValidationMessageFor(model => model.Birthdate)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>
Now we have simple database of persons. Then we need to create a controller and view to show
person data as grid view using webgrid helper class
Controller :
PersonListController.cs
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using MVC_myfirst_Mvcapplication.Models;
namespace MVC_myfirst_Mvcapplication.Controllers
{
public class PersonListController : Controller
{
private PersonContext db = new PersonContext(); // database context
for persons
//
// GET: /PersonList/
View :
PersonList >
Index.cshtml
@model IEnumerable<MVC_myfirst_Mvcapplication.Models.Person>
@{
ViewBag.Title = "People List";
}
<h2>People List</h2>
<div id ="DivGrid">
@{
var grid = new WebGrid(source: Model);
@grid.GetHtml(htmlAttributes: new { id = "DataTable" }, columns:
grid.Columns(
grid.Column("ID"),
grid.Column("First"),
grid.Column("Last"),
grid.Column("Birthdate"),
grid.Column("", header: "ToEdit", format:
@<text>@Html.ActionLink("Edit", "Edit", "Person", new { id = item.ID}, new
{ target = "_blank" })</text>)));
}
</div>
The simple grid view using webgrid helper class as shown bellow :
if we want to add some features and styles to this webgrid, then we have to use some constructed
parameters, GetHtml Parameters for WebGrid
WebGrid Constructed Parameters used in this view :
Source : Used to render Data into table. This is IEnumerable<dynamic> type, i.e. source: Model
canSort : used to enable or disable sorting data. default is enabled, this is bool type i.e. canSort : true
canPage : used to enable or disable paging data. default is enabled, this is bool type i.e. canPage : true
rowsPerPage : Used to control no.of rows per page to be rendered. Default is 10, this is Int type
i.e. rowsPerPage:3
defaultSort : used to specify the default column to sort. This is string type i.e. defaultSort : "ID"
tableStyle : Used to define a table class style for styling. This is string type, i.e. tableStyle: "PGrid"
headerStyle : Used to define a header class style for styling. This is string type, i.e. headerStyle:
"Header"
alternatingRowStyle: Used to define row class for styling even rows. This is string type i.e
alternatingRowStyle:"altRow" (for odd rows we have to use rowStyle parameter)
Content >
StyleSheet.css
body
{
background-color: #e295fc;
color: #1A1A1A;
font-size: .85em;
font-family: "Segoe UI", Verdana, Helvetica, Sans-Serif;
margin: 1.5em;
padding: 0;
}
.PGrid
{
margin:2%;
border-collapse:collapse;
width:95%;
}
.Header
{
font-weight:bold;
background-color:#60acf6;
color:#ff6a00;
text-decoration:none;
}
.PGrid th, .PGrid td
{
border:1px solid #0094ff;
padding:5px;
}
.altRow {
color:brown;
background-color:#808080;
}
View :
PersonList >
Index.cshtml
@model IEnumerable<MVC_myfirst_Mvcapplication.Models.Person>
@{
ViewBag.Title = "People List";
}
<link href="../Content/StyleSheet.css" rel="stylesheet" />
<h2>People List</h2>
<div id ="DivGrid">
@{
var grid = new WebGrid(source: Model, canPage: true, rowsPerPage:4,
defaultSort:"ID");
@grid.GetHtml(tableStyle: "PGrid", headerStyle: "Header",
htmlAttributes: new { id = "DataTable" },
columns: grid.Columns(
grid.Column("ID"),
grid.Column("First" , "Name"),
grid.Column("Birthdate"),
grid.Column("", header: "ToEdit", format:
@<text>@Html.ActionLink("Edit", "Edit", "Person", new { id = item.ID}, new
{ target = "_blank" })</text>)));
}
</div>
Finally the customized grid view data using WebGrid as shown bellow:
AJAX in MVC
JSON: JavaScript Object Notation
Why JSON
Before JSON comes use XML. Using XML is hard because XML has to be parsed with an
XML parser, so to do that developer need to define XML parser separately. But when JSON
comes it is very much easy to deal because JSON can be parsed by a standard JavaScript
function. No more need of data parses. It provide us a human-readable collection of data that
we can access in a really logical manner.
Also JSON is quicker to read and write and we can use arrays in JSON.
JSON - DataTypes
1. var jsonObj = { firstName: 'kamal'}
A Boolean (true or false)
1. var jsonObj = '{ "employees":[
2. {"firstName":"kamal", "age":"21"},
3. {"firstName":"Aruna", "age":"25"},
4. {"firstName":"Peter","age":"18"} }';
5. ]
An object (in curly braces)
1. var jsonObj = {"firstName":"Sunil", "age":"20"}
null
Json commonly using to read data from a web server, and display the data in a web
page.
The JavaScript function JSON.parse(text) can be used to convert a JSON text into a
JavaScript object:
1. var JavaScriptObj = JSON.parse(jsonObj);
Ajax requests are triggered by JavaScript code. Your code sends a request to a URL, and
when it receives a response, a callback function can be triggered to handle the response.
Because the request is asynchronous, the rest of your code continues to execute while the
request is being processed, so it's imperative that a callback be used to handle the response.
Google Maps, Gmail, YouTube and Facebook update the part of the web page without having
to reload the entire page.
Ajax Events
These are events that you can subscribe within the Ajax request object.
2. Global Event
These events are triggered on the document, calling any handlers which may be
listening.
Model
Following is a Model class named PersonModel with two properties i.e. Name and DateTime.
public class PersonModel
{
///<summary>
/// Gets or sets Name.
///</summary>
public string Name { get; set; }
///<summary>
/// Gets or sets DateTime.
///</summary>
public string DateTime { get; set; }
}
Controller
The Controller consists of two Action methods.
Action method for handling GET operation
Inside this Action method, simply the View is returned.
Action method for handling jQuery AJAX operation
This Action method handles the call made from the jQuery AJAX function from the View.
Note: The following Action method handles AJAX calls and hence the return type is set to JsonResult.
The value of the name parameter is assigned to the Name property of the PersonModel object along
with the Current DateTime and finally the PersonModel object is returned back as JSON to the jQuery
AJAX function.
public class HomeController : Controller
{
// GET: Home
public ActionResult Index()
{
return View();
}
[HttpPost]
public JsonResult AjaxMethod(string name)
{
PersonModel person = new PersonModel
{
Name = name,
DateTime = DateTime.Now.ToString()
};
return Json(person);
}
}
View
Next step is to add a View for the Controller and while adding you will need to select the PersonModel
class created earlier.
Inside the View, in the very first line the PersonModel class is declared as Model for the View. The
View consists of an HTML TextBox element and a Button. The Button has been assigned a jQuery
click event handler and when the Button is clicked a jQuery AJAX called is made to the Controller’s
action method.
The following figure describes a jQuery AJAX call in ASP.Net MVC
The URL for the jQuery AJAX call is set to the Controller’s action method i.e. /Home/AjaxMethod. The
value of the TextBox is passed as parameter and the returned response is displayed using JavaScript
Alert Message Box
@model jQuery_AJAX_MVC.Models.PersonModel
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width"/>
<title>Index</title>
</head>
<body>
<input type="text" id="txtName"/>
<input type="button" id="btnGet" value="Get Current Time"/>
<script type="text/javascript"
src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script type="text/javascript">
$(function () {
$("#btnGet").click(function () {
$.ajax({
type: "POST",
url: "/Home/AjaxMethod",
data: '{name: "' + $("#txtName").val() + '" }',
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (response) {
alert("Hello: " + response.Name + " .\nCurrent Date and
Time: " + response.DateTime);
},
failure: function (response) {
alert(response.responseText);
},
error: function (response) {
alert(response.responseText);
}
});
});
});
</script>
</body>
</html>
Implementing Ajax based login involves many of the same steps as the normal forms authentication.
However, the login page doesn't send user ID and password to the server through a standard form
submission. Instead, user credentials are sent to the server via an Ajax request. The credentials are
then validated on the server and the result of the verification process is conveyed to the client. If the
login attempt was successful, the user is taken to the secured area of the website.
First of all you need to configure a database for membership services. This is done with the
help of aspnet_regsql.exe tool. Open Visual Studio developer command prompt and issue the
said command to open the configuration wizard. Simply follow the wizard to configure your
database. For example, here I am configuring Northwind database to support membership
services.
Configure forms authentication and membership provider
Next, open the web.config of the web application and configure the authentication scheme as
shown below:
<connectionStrings>
<add name="connstr" connectionString="data source=.\sqlexpress;
initial catalog=Northwind;integrated security=true"/>
</connectionStrings>
<system.web>
<authentication mode="Forms">
<forms loginUrl="~/account/login" defaultUrl="~/home/index"></forms>
</authentication>
...
</system.web>
The <authentication> tag sets the authentication mode to Forms. The forms authentication is
configured to have login page as ~/account/login and default page as ~/home/index. The
<connectionStrings> section defines a database connection string for the Northwind database.
This connection string is used while configuring the membership provider.
To configure the membership provider add the following markup to the web.config file:
<membership defaultProvider="p1">
<providers>
<add name="p1" connectionStringName="connstr"
type="System.Web.Security.SqlMembershipProvider" />
</providers>
</membership>
Then add a controller to the Controllers folder - AccountController. The Account controller
contains code that validates a user. The Login() and ValidateUser() action methods of the
Account controller are shown below:
[HttpPost]
public JsonResult ValidateUser(string userid, string password,
bool rememberme)
{
LoginStatus status = new LoginStatus();
if (Membership.ValidateUser(userid, password))
{
FormsAuthentication.SetAuthCookie(userid, rememberme);
status.Success = true;
status.TargetURL = FormsAuthentication.
GetRedirectUrl(userid, rememberme);
if (string.IsNullOrEmpty(status.TargetURL))
{
status.TargetURL = FormsAuthentication.DefaultUrl;
}
status.Message = "Login attempt successful!";
}
else
{
status.Success = false;
status.Message = "Invalid UserID or Password!";
status.TargetURL = FormsAuthentication.LoginUrl;
}
return Json(status);
}
The Login() action method simply returns the Login view. The ValidateUser() method is
important to us because this method validates the user credentials and is called via Ajax. The
ValidateUser() method takes three parameters - userid, password and rememberme. Inside, it
calls ValidateUser() method of the Membership object to decide whether the user ID and
password is correct. The ValidateUser() method also creates an instance of LoginStatus class
- a POCO that is intended to store the status of the login process. The LoginStatus class looks
like this:
Coming back to the ValidateUser() method, if the user credentials are valid a forms
authentication cookie is issued using the SetAuthCookie() method. The LoginStatus object is
populated with the required information. Notice how the TargetURL is determined using
GetRedirectUrl() method and DefaultUrl properties of the FormsAuthentication class.
If the login attempt was unsuccessful, LoginStatus object is populated with error information.
Finally, LoginStatus object is sent back to the caller using Json() method. Remember that
ValidateUser() method will be called using Ajax and hence should return data to the browser
in JSON format.
The Login view consists of a textbox, a password box, a checkbox and a button. Clicking on
the Login button initiates an Ajax request to the ValidateUser() method you created earlier.
The jQuery code responsible for calling the ValidateUser() method is given below:
$(document).ready(function () {
$("#login").click(function () {
$("#message").html("Logging in...");
var data = { "userid": $("#userid").val(),
"password": $("#password").val(),
"rememberme":$("#rememberme").prop("checked") };
$.ajax({
url: "/account/validateuser",
type: "POST",
data: JSON.stringify(data),
dataType: "json",
contentType: "application/json",
success: function (status) {
$("#message").html(status.Message);
if (status.Success)
{
window.location.href = status.TargetURL;
}
},
error: function () {
$("#message").html("Error while authenticating
user credentials!");
}
});
});
});
Observe this code carefully. Upon clicking the login button a progress message is displayed
in a message <div> element. The code then forms a JavaScript object that has three properties
- userid, password and rememberme. These property names must match the parameter names
of the ValidateUser() action method you created earlier. Then $.ajax() of jQuery is used to
make an Ajax request to /account/validateuser. The type of the request is set to POST. The
data setting contains the stringified version of the data JavaScript object you just created. The
dataType and contentType properties are set to json and application/json respectively. These
two properties represent the response format and the request MIME content type respectively.
The success function receives a status object. This object is a JSON representation of
LoginStatus object you return from the ValidateUser() method. If the Success property is true
it means that the login attempt was successful and the user is redirected to the TargetURL
using window.location.href property. If the login attempt fails an error message is displayed
in the message <div>. The error function is invoked if there is any error making the Ajax call
and simply displays an error message to the user.
If a login attempt is successful the use is taken to the Index view. So, add the Home controller
and also the Index view. The Home controller is supposed to be a secured one and hence add
[Authorize] attribute on top of the Index() action method or the HomeController class.
[Authorize]
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
}
<body>
<h1>Welcome @Membership.GetUser().UserName!</h1>
</body>
To test the application you just developed you need to create a new user account. You can do
so either by creating a registration page or by adding a few test users in the Global.asax. For
the sake of this example the later approach is alright. Here is how you can create a new user.
That's it! The Ajax login for your MVC application is ready :-)
Open Visual Studio and create a new ASP.NET MVC 4 Web Application (Internet
Application) named “MvcAjaxApplication”, choosing the Basic option for template. We will
build a web application where users can retrieve Product objects and manipulate them as
well. All actions are going to be handled through Ajax calls. First of all, we need to create our
Domain model so, go ahead and create a Product class inside the Models folder.
1
2
3 namespace MvcAjaxApplication.Models
{
4 public class Product
5 {
6 public int Id { get; set; }
7 public string Name { get; set; }
8 public string Description { get; set; }
public decimal Price { get; set; }
9 public int UnitsInStock { get; set; }
1 }
0 }
1
1
We won’t use mock Product objects, but instead we are going to store our products in a
Microsoft SQL Server database. Log in to your SQL Server Management Studio and create a
new database named “ProductsStore”. Right click the Tables folder and add a new Table with
the following Columns. Save the new table and name it Products.
Add some records for your Product objects. Feel free to add your own if you want.
It’s time to connect our Domain Model with this database. We are going to use the LINQ to
SQL perspective, so if you aren’t familiar with this please read this post. Add a reference to
System.Data.Linq assembly if it hasn’t already exist. Change your Product class as follow.
1 using System.Data.Linq;
using System.Data.Linq.Mapping;
2
3
namespace MvcAjaxApplication.Models
4 {
5 [Table(Name="Products")]
6 public class Product
7 {
[Column(IsPrimaryKey=true)]
8 public int Id { get; set; }
9 [Column]
1 public string Name { get; set; }
0 [Column]
1 public string Description { get; set; }
[Column]
1 public decimal Price { get; set; }
1 [Column]
2 public int UnitsInStock { get; set; }
1 }
}
3
1
4
1
5
1
6
1
7
1
8
1
9
2
0
Create a folder named “Infrustructure” and add a C# class file named “ProductsContext.cs”
with a “Connections” class as follow. Paste the following code and make sure you change
your Data Source respectively.
1using MvcAjaxApplication.Models;
2using System.Data.Linq;
3
4namespace MvcAjaxApplication.Infrustructure
{
5 public class Connections
6 {
7 public static string connection = "Data Source=developer-pc;Initial
8Catalog=ProductsStore;Integrated Security=True";
9 }
Enough with the modeling, let’s test if we can access our database Products table. Create an
Empty MVC “HomeController” controller in the controllers folder.
1 using MvcAjaxApplication.Infrustructure;
using MvcAjaxApplication.Models;
2
using System.Data.Linq;
3
4 namespace MvcAjaxApplication.Controllers
5 {
6 public class HomeController : Controller
7 {
DataContext context;
8
9
public HomeController()
1 {
0 this.context = new DataContext(Connections.connection);
1 }
1
1 public ActionResult Index()
{
2 Product[] products = context.GetTable().ToArray();
1 return View(products);
3 }
1
4 }
}
1
5
1
6
1
7
1
8
1
9
2
0
2
1
2
2
2
3
Right click in your Index action method and create a new View, named Index with a strongly
typed of IEnumerable<Product> type. Paste the following code, build your application and
run it. You should see all your database products.
1 @using MvcAjaxApplication.Models
@model IEnumerable<Product>
2
3
@{
4 ViewBag.Title = "Products";
5 }
6
7 <h2>My Products</h2>
8
9 <table>
<tr>
1 <th>ID</th>
0 <th>Name</th>
1 <th>Description</th>
1 <th>Price</th>
1 <th>UnitsInStock</th>
</tr>
2 @foreach (Product p in Model)
1 {
3 <tr>
1 <td>@p.Id</td>
<td>@p.Name</td>
4 <td>@p.Description</td>
1 <td>@p.Price</td>
5 <td>@p.UnitsInStock</td>
1 </tr>
6 }
</table>
1
7
1
8
1
9
2
0
2
1
2
2
2
3
2
4
2
5
2
6
2
7
2
8
Ok, it’s time to create some Ajax calls. Well, the idea is this. We will have some static
HTML markup in the Index View, an empty div element and a button. When the user clicks
the button, an Ajax call will invoke a GetProducts action method which in turn, will return a
partial view. We ‘ll put the contents of this partial view in the empty div element. Let’s do it.
Create a GetProducts action method in the HomeController. Also, make sure you change the
Index action’s code later.
Right click inside the GetProducts action and add a new Partial View. Fill the Window as
follow.
Change the new Partial View’s contents. You will notice that we pasted almost the same
contents with the Index View.
1 @using MvcAjaxApplication.Models
@model IEnumerable<Product>
2
3
<table>
4 <tr>
5 <th>ID</th>
6 <th>Name</th>
7 <th>Description</th>
<th>Price</th>
8 <th>UnitsInStock</th>
9 </tr>
1 @foreach (Product p in Model)
0 {
1 <tr>
<td>@p.Id</td>
1 <td>@p.Name</td>
1 <td>@p.Description</td>
2 <td>@p.Price</td>
1 <td>@p.UnitsInStock</td>
</tr>
3 }
1 </table>
4
1
5
1
6
1
7
1
8
1
9
2
0
2
1
2
2
1 @using MvcAjaxApplication.Models
2
@{
3
ViewBag.Title = "Products";
4 }
5
6 <div style="width:600px; margin-left:auto; margin-right:auto">
7 <div style="background-color: lightgray">
8 <h2>My Products</h2>
</div>
9 <p>Click the button to Get Products with an Ajax call</p>
1 <input id="btnAjax" name="btnAjax" type="button" value="Get Products"
0 />
1 <div id="products" style="background-color:lightskyblue"></div>
1 </div>
1
@section Scripts {
2 <script>
1 $('#btnAjax').click(function () {
3 $.ajax({
1 url: '/Home/GetProducts',
contentType: 'application/html; charset=utf-8',
4 type: 'GET',
1 dataType: 'html'
5
1 })
6 .success(function (result) {
1 $('#products').html(result);
})
7 .error(function (xhr, status) {
1 alert(status);
8 })
1 });
9 </script>
}
2
0
2
1
2
2
2
3
2
4
2
5
2
6
2
7
2
8
2
9
3
0
3
1
3
2
3
3
3
4
We have bound the “btnAjax” button’s click event to an Ajax call. This call targets the Home
controller’s GetProducts action (url parameter). If the call is successful we simply place the
returned html into the “products” div. So simple. Run your application and click the button.
1 @using MvcAjaxApplication.Models
2
@{
3 ViewBag.Title = "Products";
4 }
5
6 <div style="width: 600px; margin-left: auto; margin-right: auto">
7 <div style="background-color: lightgray">
8 <h2>My Products</h2>
</div>
9 <p>Click the button to Get Products with an Ajax call</p>
1 <input id="btnAjax" name="btnAjax" type="button" value="Get Products"
0 />
1 <div id="products" style="background-color: lightskyblue"></div>
1 </div>
1
<div id="changePriceDiv" style="display: none">
2 <hr />
1 <table>
3 <tr>
1 <th>Product ID</th>
<th>New Price</th>
4 </tr>
1 <tr>
5 <td>
1 <input id="txtId" name="txtId" type="text" /></td>
6 <td>
<input id="txtPrice" name="txtPrice" type="text" /></td>
1 </tr>
7 </table>
1 <input id="btnChangePrice" name="btnChangePrice" type="button"
8 value="Change Price" />
1
9
2
0
2
1
2
2
2
3
2
4
2 </div>
5
2
6
2
7
2
8
2
9
3
0
3
1
You need to show this div, when your retrieve your products. Change your success Ajax
callback, like this.
1 $('#btnAjax').click(function ajaxCall() {
$.ajax({
2
url: '/Home/GetProducts',
3 contentType: 'application/html; charset=utf-8',
4 type: 'GET',
5 dataType: 'html'
6
7 })
.success(function (result) {
8 $('#products').html(result);
9 $('#changePriceDiv').show().appendTo($('#products'));
1 })
0 .error(function (xhr, status) {
1 alert(status);
})
1 }
1
2
1
3
1
4
1
5
1
6
Now if you click the GetProducts button you will a get this result.
We need to add a new action in our HomeController, to update a product’s price. The action
will get an int parameter for the product’s id and a decimal parameter for the new Price .
Then, using LINQ to SQL will change the respective product’s price, save it in database and
finally, it will return the same partial View as the GetProducts action. The user though, is
going to see only the new product’s price changed in the user interface.
The last thing we need to do, is to bind the “btnChangePrice” button’s click event to an Ajax
call targeting the ChangeProductPrice action. Add the following code to the Index View. Pay
attention on the data attribute and how is used to sent your Id and New Price values.
1 <script>
$('#btnAjax').click(function ajaxCall() {
2 $.ajax({
3 url: '/Home/GetProducts',
4 contentType: 'application/html; charset=utf-8',
5 type: 'GET',
6 dataType: 'html'
7
8 })
.success(function (result) {
9
$('#products').html(result);
1 $('#changePriceDiv').show().appendTo($('#products'));
0 })
1 .error(function (xhr, status) {
1 alert(status);
})
1 }
2 );
1
3
1 $('#btnChangePrice').click(function () {
4 var idVal = $('#txtId').val();
1 var newPriceVal = $('#txtPrice').val();
$.ajax({
5 url: '/Home/ChangeProductPrice',
1 contentType: 'application/html; charset=utf-8',
6 data: {id : idVal, newPrice : newPriceVal },
1 type: 'GET',
dataType: 'html'
7
1
})
8 .success(function (result) {
1 $('#products').html(result);
9 })
2 .error(function (xhr, status) {
alert(status);
0 })
2 });
1 </script>
2
2
2
3
2
4
2
5
2
6
2
7
2
8
2
9
3
0
3
1
3
2
3
3
3
4
3
5
3
6
3
7
3
8
3
9
That’s it. Build and run your application. Click and retrieve your products. Select an Id and
enter a new Price (We didn’t write any validation code, so make sure you enter valid values).
It’s very important to know how to use Ajax and retrieve data in your ASP.NET MVC
applications.