source code: Download CP_MasterDetail.zip
Introduction
This Article is for beginners, you learn with real world example how to take the default implementation of ASP.NET MVC for Master-Details to the next level
The Problem
MVC infrastructure allows easy and almost effortless display a list of records
from a DB. As well as it allows (out of the box) drilldown/delete and update
each record, but not always it the most convenient way.
In this tutorial, we will see three methods of presenting masterDetails
solution using MVC.
The Scenario:
We have a requirement to
develop a site that displays a list of customers with the option to drill down a
customer and view full details.
So let's see how we implement this
with MVC4 in a very simple way.
To be focused on the solution,
we will use the minimum... No layers, IOC, tests and everything the book
says...
The Solution (Part I) :
- First, using VS2012, let’s
create a new asp.net mvc4 - We will choose Internet
Application.
3. In order to create our
object model we will use EntityFramework
Right click the Models folder and choose New
Item…
Select ADO.NET Entity Data Model from Data
Templates folder
Change the name to: Northwind.edmx
Click Add.
Click next, to create the model from database
Choose your database…
To create a new connection, click on New
Connection and enter your DB server name and Database name
(*notice: the connection string will be added
by VS to our web.config)
Choose Customers table and click Finish.
4.
If we look at the project
structure we will see the generated model - Northwind.edmx and visual
representation of the chosen customer table.
5.
Under Northwind.edmx, we can
see the class created for us called Customers.
6.
Important! In order the use
the new data model we just created we must build the project.
MVC infrastructure allows us to work with the
object model in a simple, easy and without much effort.
7.
We will create a new
controller called Customer.
8.
Choose the template that
will create views with the object model we created earlier and click ADD
9.
If we examine the structure
of the project, we will see that new CustomerController and some new views has
been create. This will let us work with the model.
10.
Before running the code, in
RouteConfig file, we will set routing to
direct by default to newly created CustomerController
11.
To reduce slightly the
customer table, we will use Take(5)
method in the Index action in CustomerController.
12.
We also reduce slightly the number of columns in the
Index View, to get a smaller table.
13.
For the drilldown to work ,
replace the following code:
From-
To-
15.
Finally, hit F5 to run the
project. You should see the The result screen below:
16.
Clicking on the Details
refer us to the customer details page
Very easy and very simple...
We have implemented the requirement. We have a list of customers with
the option to drilldown to customer’s information.
But end users as end users, they’re almost never satisfied with the
results!
They do not like the fact that in order to see the customer information
they need to move to another screen, and again return to the customers, they
want to see the customer details and the list of customers on the same page!
No problem - let's deliver:
The Solution (Part II) :
We will use a new model that will contain the following data structure:
·
List of customers to view.
·
Customer selected (if
selected).
·
Client code selected (if
selected).
Here is the new model I’ve created. Called "CustomerMasterDetailsModel"
under the Models folder:
We will change the Index Action in the Controller in order to use new
model. The code should look like this:
The first change I'll make is to insert Optional parameter in case the
user select a customer.
At the first time, the parameter will be null, so we'll pass to the View
the full list of customers.
The second time we get here, will be due to a customer selection by the
end user. This time the parameter will hold the customer id value. In addition
to customer list we also have to locate the selected customer, add it to the
model along with the selected customer id and pass it to the View.
As you probably guessed, the Index View will need few changes too:
1.
We will Replace the
existing model (at the top of the page):
From
To
2.
Now we have to deal with
the two sections of code within the View. One is the customers and the other
one is the selected customer information.
We will delete the existing code and create a
new one for the two sections.
We'll start with the list of customers - (We
will use UL element instead Table) and wrap it inside section element called:
CustomerMasterList:
As you can see We will represent each
customer from the customers list as a UL and add an ActionLink (that will be
converted to <a href tag). Clicking on this link will lead us to the same
controller, to the Index Action and pass the Customer Id as a parameter.
The second code section called:
CustomerDetails will handle displaying the customer information (if selected).
Note row 31, the code will run only if a customer was selected.
This is what we get after running the project:
Now when we click on the link View Details, we will be directed
to the following URL: localhost: 2075/Customer/Index/ALFKI
When the IndexAction runs, it will validate that a customer id was sent.
If so, it will return the new model that contain the customer list, the
selected customer object & selected customer id.
Very easy and very simple...
We fulfilled our duty…implementing our customer requirement. Now we have
a list of customers with the option to drilldown to a customer information in
the same page.
No??? Again???… Our customers are disappointed with the result!
They don’t like the fact that every time they click customer details the
see the page refreshed, especially if they are in the middle the page and the
refresh lead them back to the top.
Well…..you know the say: the customer is always right
To support the new requirement we will use PartialViews and JQuery AJAX
capabilities.
Let's continue...
The Solution (Part III) :
The following image illustrates the changes we need to make in order to
support the new request:
I'll transfer the code that responsible of showing the customer details
to a new PartialView, and add some client side code to the Index view, that
will help us to make ajax call to the action method on the server. The server
then return an HTML code containing the customer details so we can inject it to
a new div(place holder) that we will create soon. This changes will help us to implement the new requirement.
1.
Create the PartialView
right click on the customer folder under the Views and click "Add".
Here is the configuration values of the new
View:
In the created view we'll delete the last two
rows (that handle the navigation functionality (we won't use it.
2.
Changes on the Index view:
first we'll delete the section element with the "CustomerDetails" id.
We'll add instead a new empty div with
"CustomerDetail" id, this div will present the HTML of the selected
customer details.
We'll make some modification to the first
code segment that responsible presenting the customer list, we'll replace the
following <li> element:
With this <li> element:
Pay attention that we changed the
"Index" Action name with "CustomerDetail"(that we are going
add right away), we also added a new "css class" parameter that will
use as a selector to identify the <a> element.
The last thing left to do is to add client side script that will connect
between the click event of the <a> element and the Ajax command (using
the class selector).
When a user click the <a> element , will make an Ajax call to the
CustomerDetail Action within the Controller, the Controller will return a
partial view in HTML format that will be inject to the div element.
Here is the script attached to the end of the
view:
3.
Adding a new Action to the
Controller
we will create a new action (we know its name as we set it at the view level)
Here is our brand new Action:
Inside the Action we use the Find method
(passing along the id) to get the appropriate customer object , we the return
the Partial view by specifying its name and also the current found customer,
this will eventually return an HTML code with current customer details to be
hosted inside our Div.
And we done!!!
Now let's hit F5 to run the project,
We'll get the main page with a list of Customers:
We then click the "View Details" Link and Walla we get our
customer details with a full refresh! J
* big thx to Golan Sheetrit for his help