Area in MVC - giving a nice physical structure & dealing with template bug
In
my last blog post I talked about ‘retrieving views from different folders in MVC’
and it works cool when we want view pages always inside Views folder (which is
on the project root) but our requirement not ends here.
The new version "Area in MVC 5" is available here.
Introduction
Hope
this helps.
The new version "Area in MVC 5" is available here.
Introduction
As
you know MVC Architecture separates all the logics: model logic, business logic
and presentation logic and provides a very clean and light weight application
in total. One more good thing that I love is, it provides logical separation
physically also. In physical logic separation controllers, models and views are
kept in another folder on root with the help of Area. Areas provide a way to
separate a large MVC Web Application into smaller functional groupings inside
MVC Application and each group contains MVC Structure (Ex. Model, View and
Controller folders). Area was introduced with MVC2 release.
Now, let’s talk about a
requirement
Assume,
you are working on a MVC Project where you have to work on account section,
administrative section, support section, billing section and so on. In this
case you should use Area which will provide a strong physical structure. See
how it looks like.
You
can see every section has MVC Architecture Controller, Model, View (view will
have a Shared folder where you can place your layouts, partial views etc) and
an AreaRegistration (which contains RegisterArea method similar to
RegisterRoutes).
How to Create It
Here
I’m going to create CRUD views for Students inside Area. I will take the
advantage of EF Code First. Let’s walk through the simple steps.
Step 1
Right
click on Project and then pick Add|Area.
Step 2
Now
this will bring a dialog-box. Type the Area name which is similar to section
name (you can see it in first image, Admin, Billing, Support).
I typed
‘Student’, and hit Add button.
Step 3
You
will see following structure.
Step 4
As
I said, I am going to take the advantage of EF Code first so I need a model
class, here it is.
public class StudentViewModel
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Address { get; set; }
}
Step 5
In
this step I will name the controller ‘Student’ and in template select ‘MVC
controller with read/write actions and views, using Entity Framework’. Also,
select model class which is Student and then create a new DbContext by name
StudentContext, finish with clicking on Add button.
In the next step we will run the application but before this
you should check this entry in Global.asax file, it should be there on the top.
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
WebApiConfig.Register(GlobalConfiguration.Configuration);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
AuthConfig.RegisterAuth();
}
Step 6
Now
we are all set to run the project and I expect your app should run, if not
don’t throw bricks on me.
Well,
in my case I fall in an error. I noticed a nice bug (because I love bugs) in product
template. (I will figure out this error in Step 7), you just keep reading:
An error occurred creating the configuration section handler for
system.web.webPages.razor/host: The given assembly name or codebase was
invalid. (Exception from HRESULT: 0x80131047)
Notice
in above image I’m trying to navigate http://localhost:33103/Student/Student.
In this URL, the first ‘Student’ segment is my area name and second ‘Student’
segment is my controller name.
Why I’m passing controller
name and can we make it default?
Keep
reading, you will get your answers.
Let’s
open StudentAreaRegistration.cs (find this file in ‘Student’ area) file.
Open
this file and look at the codes.
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"Student_default",
"Student/{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional }
);
}
You
can see I am registering a new area and in the route we have following URL
format:
"Student/{controller}/{action}/{id}"
Notice
following things:
i)
Controller is preceded by ‘Student’ which is area name.
ii)
In above RegisterArea we have default value for action and id is optional.
iii)
We don’t have default value for controller.
If
you want to provide default controller name, do it this way.
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"Student_default",
"Student/{controller}/{action}/{id}",
new { controller = "Student", action = "Index", id = UrlParameter.Optional }
);
}
Now,
only hitting http://localhost:33103/Student URL
will work, because we hardcoded the controller value.
Step 7
I
figured out the issues that we experienced in step 6. When I opened the Web.config
file which is inside Areas|Student|Views|Web.config, I found some really
strange entries for WebPageVersion and MvcVersion. I will call this MVC Template
bug which is in product.
And
here is the workaround:
i)
Find ‘__WebPagesVersion__.0.0’
and replace it with ‘2.0.0.0’.
ii)
Find ‘__MvcVersion__.0.0’
and replace it with ‘4.0.0.0’.
Do
a build and try running.
Yah!
It is running now and the only thing left is its presentation layout.
Step 8
To
apply layout, I’ll simply copy the _ViewStart.cshtml file, look at the image.
[Tip: To copy it, drag the file by
pressing Ctrl Key in Solution Explorer]
Now,
try running and enjoy.
I am new for MVC so i want basic concept of MVC
ReplyDeleteArea
ReplyDeleteI am finding difficulties to arrange the area folder for my project
This is Job application website and having mainly following type of pages/section
1) - Admin Pages - Only for Admin user(site owners) - so only authenticated(logged in) admin users case see those pages/section
example - Post_Jobs_Page, Edit_Job_Page, Change_Admin_Password, Add_News_Events_Page etc.
2) - Job seeker Pages - only for Job seekers - so only authenticated(logged in) Job Seeker users case see those pages/section
example - change_Password, Edit_Profile, Applied_Jobs etc
3) - Common Pages - where any job seeker either authenticated(logged in) or without authentication can visit those page
Search_Jobs, ContactUs, AboutUs etc
So I am not sure how to organize MVC folder structure - how may areas should i add and where to put which files
nice article
ReplyDelete