ASP.NET MVC Folder Conventions - asp.net-mvc

ASP.NET MVC projects follow naming and folder conventions for Models, Views and Controllers. For other code (ex: Action Filters, Delegating Handlers, etc), is there a best practice as to where to locate these in the project's folder structure?

A good way to find out is by checking out what the actuall best practices are is to see Open Source projects. IIRC the NuGet Gallery was written by the Asp.Net MVC guys, so it would serve as a good example for what they view as Best Practices while still being an actual product:
https://github.com/NuGet/NuGetGallery
It looks like they added their FilterAttributes, HtmlHelpers, etc. to the root of the project : https://github.com/NuGet/NuGetGallery/blob/master/Website/RequireRemoteHttpsAttribute.cs
Also, Phil Haack and David Ebbo worked on the Asp.Net MVC team, and you can check out their GitHub repos for what they like to do.

There is no standard way as such. Different practitioners have put up various methods but all have some pros and cons. However, based on applicable design constraints, here are some pointers :
Reusability
If you want your Action Filters, Delegating Handlers etc to be reusable, then placing them in a dedicated folder in asp.net mvc webroot will do the job. That way all such filters will have global scope and can be used as needed.
Pluggability
If want to create a pluggable module out of the filters etc. It might be worth placing them in a separate DLL altogether. The library can be thought of as a black box which takes all contextual information as function inputs and can be reused as required.
I liked the pluggable architecture of Orchard CMS http://www.orchardproject.net/
I asked a similar question sometime back on how to organize models in asp.net mvc project. Unfortunately didn't get much response.
Models in asp.net mvc 3 areas

Related

ASP.NET MVC - separating large app

I've been puzzled by what I consider a contradiction in terms: ASP.NET MVC claims to be furthering and supporting the "separation of concern" motto, which I find a great idea.
However, it seems there's no way of separating out controllers, model or views into their own assembly, or separating areas into assemblies.
With the fixed Controller, Model and View folders in your ASP.NET MVC, you're actually creating a huge hodge podge of things. Is that the separation of concerns, really?? Seems like quite the contrary to me.
So what I'm wondering:
how can I create an ASP.NET MVC solution that will either separate out controllers, the model, and the folders full of views, into separate assemblies?
how can I put areas of ASP.NET MVC 2 into separate assemblies?
or how else do you manage a large ASP.NET MVC app - which has several dozen or even over a hundred controllers, lots of model and viewmodel classes, and several hundred views?
I think you're looking for Areas in ASP.Net MVC 2. There are some things to uncomment in the CSProj files, but after that it will copy the views over when you build. I don't think there is any requirement that the Controller or Model classes be in the same assembly as the views.
Walkthrough: Creating an ASP.NET MVC Areas Application Using Multiple Projects
Controllers: AFAIK you shouldn't have to do anything special to throw controllers into their own assembly. At the very most all you'd have to do is override the GetControllerType method of your ControllerFactory.
Models: Zero restrictions on where you put your models. Although this is frowned upon I regularly use persistent objects from an Nhibernate/other ORM layer or WCF/service layer DTO thats are located in a separate assembly as my views. This works the same way using WebForms.
Views: Views in a separate assembly must be marked as embedded resource and then you must use a custom VirtualPathProvider that knows how to get the views from an resource instead of the file system. views from an resource instead of the file system. Again this is the exact same technique you would use for WebForm development.
Regarding mcintyre321 and his Portable Areas answer: The linked project does barely anything custom and simply wraps up the existing MVC 2 extensibility points into an easier to use abstraction. Its barely "custom" and more syntactic sugar.
You manage a large MVC app just like you'd manage any other large app. I dread opening up a 500 page WebForms project because you never quite know whats in each of those code behinds. With MVC distinct functionality is mostly within its right place. Its not contrary at all.
Separating code into separate assemblies is orthogonal to separation of concerns. Where the code lives is not a "concern". Separation of concerns has to do with responsibilities and direction of dependencies of various components. For example, Views are responsible for rendering the output, and the controller knows about the views, but the views don't really have intimate knowledge of the controller.
Likewile, Models don't know anything about either views or controllers, but both views and controllers will know about the model.
However, back to your question. As jfar points out, moving controllers and models into another assembly is trivially easy and will work. Moving views into another assembly is trickier. Embedded resources with a custom virtual path provider is one way, but not one we generally recommend for a high performance site. But if it meets your needs, go for it.
MVC is very extensible and does not require to adhere to the Controller, View, and Model folder structure. You can place the controllers anywhere you would like, however if they are located in another assembly you will need to implement your own controller factory that knows how to locate them. Here is an example for locating your controllers with Windsor.
Your models/view models can be where ever you want. You simply need to reference their namespace in the web.config so views know where to look. (At least I know this is true with the Spark view engine.)
You put your views in any web project. My usual strategy is to create a plain web (non-mvc) project that contains the views folder. (This could even be a legacy web app!) Then all my controllers go in a separate class library. My view models and services go in another.
As far as structuring folders, I usually center my hierarchy around domain concepts. I'd have a folder in each project for Users, Products, Orders, etc. I never have a Models or Controllers folder anywhere.
You need to use portable areas see http://www.lostechies.com/blogs/hex/archive/2009/11/02/asp-net-mvc-portable-areas-part-2.aspx

ASP.NET MVC Project Structure for larger sites

I'm surprised I can't find more discussions out there about an issue that is really bothering me on our project using ASP.NET MVC.
How can you deal with a Visual Studio solution that has multiple projects? The MVC framework has the Models/Views/Controllers folder in the main project. But what if you want to break up your solution into multiple projects along logical groupings and bring the models/views/controllers along with it? When I think ahead to the end of the project, there will be many classes in each of these folders. It doesn’t paint a cleanly organized structure that will aid maintenance. We’d like a way to either move the classes to the projects that they relate to or at least use a folder structure to aid in the organization.
I assume that one option would be to use the same namespace in all of the other projects as is used by the main project, but I’m not a huge fan of that approach b/c this is not the approach that we’ve normally taken when defining our namespace.
I suppose we could at least create sub folders inside of the M/V/C folders and not carry forward the folder names to the namespaces. I’m assuming then that the classes could be found?
Some background on our project: It is a public facing web site that has many business transactions that the user can perform (about 50-60). Each transaction has a series of web pages that the user navigates through, in order to accomplish the different services provided by the site. We are using a single controller for each transaction (there have been long discussions on whether we should have a controller defined for each transaction or if we should use a higher level grouping and therefore reduce the number of controllers, but some information that we've encountered on the web (http://codebetter.com/blogs/ian_cooper/archive/2008/12/03/the-fat-controller.aspx) brought us to this decision.)
What are some recommendations? Have others solved this issue in a way that they are happy with?
Thanks
Jon.
Have a look at Areas.
Areas is a concept borrowed from MonoRail, which organizes controllers into logical folders.
http://haacked.com/archive/2008/11/04/areas-in-aspnetmvc.aspx
Areas are supported in Asp.Net MVC2.
Scott Gu has a blog talking about the Area Support here.
From his post.
Each area can be implemented as a
separate ASP.NET MVC project which can
then be referenced by the main
application. This helps manage the
complexity when building a large
application and facilitates multiple
teams working together on a single
application together
I always delete the "models" folder and reference separate class libraries that represent my business logic layers and data access layers. I also have some solutions where my controllers are kept in separate projects from my views. I agree that in larger applications, the single project model is inappropriate. Even in smaller apps, especially where model code must be shared with other applications, putting model classes in the actual MVC project is a bad idea.

ASP.NET MVC - Solution Layout Suggestions

I have been working with ASP.NET MVC for a couple of months now and I'm still not happy with the layout of my project's solution. I am trying to construct a mid-sized website CMS that is as portable and reusable as possible and there are some obvious problems in the design of it. I am looking for some advice regarding how I should structure my solution in consideration of separation of concerns. I've found a similar question here, but it doesn't really target some of the issues I am facing.
Right now this is how my solution is laid out:
+Project.Controllers - All Controller classes
P+roject.Controllers.Tests
+Project.Core - Utility classes including repetitive tasks and some configuration handlers (this project needs to be better fleshed out)
+Project.Core.Tests
+Project.Models - Model classes, Entity Framework context, and Repository classes
+Project.Models.Tests
+Project.Web - All Views and Content
One major thing I am currently missing is a place to stick my business logic and I feel I've been wrongly placing business logic in my repository classes as well as intermingling it in controller actions. Obviously, I'm very aware of this problem, I'm just not sure where I should placing my business logic in that solution layout. Does my solution structure need to change or can I safely keep that business logic in my Models project? Also, I really don't like that my EF Context is in the Models class, but I don't know of a way to isolate the data layer code from the Entity Classes needed in my model.
How is everyone else laying out their production ASP.NET MVC solutions?
You might want to check out the layout the S#arp architecture project uses or the onion architecture as used in the Code Camp Server MVC reference application. Both projects have had allot of effort put into them by different people to get a good sepperation of concerns in the context of asp.net MVC and domain driven design.
Personally I'm only learning MVC. My experience comes from ASP.NET WebForms but I would go with the layout proposed in the link you gave. The second answer, that is:
Models
Views
Controller
Services
Tests - one for each project.
I would take EF Context and Repositories out of Models and into a data access layer, Project.Data and put your business objects in Project.BusinessLogic (?).
This gives the benefit of putting the two assemblies (Project.Data and Project.BusinessLogic) in other apps you might build on the same domain. That means your next project has a very useful starting point.
Hope that helps,
Dan

Asp.Net MVC Identify Site via Url

I have an application that will support multiple sites. The site will be determined based on the url.
For example
http://myapp/site/abc123/...
and
http://myapp/site/xyz123/...
The site code will drive a lot of the functionality for example themes, available modules, etc...
Questions:
1-)I need to validate the site code is valid and if it isn't, it should direct the user to an info page. I was looking at using IRouteConstraint, is this appropriate? Are there other/better options?
2-)Any gotchas with this approach (using url to identify site)? Is there are better approach?
Solution
I ended up creating a Custom ActionFilter and check the sitecode in the OnActionExecuting event. That seems to work well and fit better than the IRouteConstraint.
The system I have implemented uses Urls to identify unique page content within a single site and the routing process is pretty straightforward. That being said, you may want to consider making use of Areas in your MVC application. With Areas you can have multiple sections to your website that all have their own MVC structure which can run semi-independently.
Essentially, you will have one base routing definition that lays out some defaults and then the rest of the "sites" will define their own routes pointing to controllers and views in a separate location. It's pretty easy to set up, you'll just need to make sure you're using version 2.0 of ASP.NET MVC. Here's a decent looking tutorial on ASP.NET MVC Areas and Routes. In the current model which MVC 2.0 supports you'll have a single Web project for each area, but that is not necessarily a requirement. Phil Haacked has some code for ASP.NET MVC Single Project Areas if you're looking for another example of the technique, although you, personally, will probably benefit more from the first article.
So long as you define good routes that have clear and measurable constraints, you shouldn't have too much trouble laying out the website you've described.
I ended up creating a Custom ActionFilter and check the sitecode in the OnActionExecuting event. That seems to work well and fit better than the IRouteConstraint.

What Is ASP.Net MVC?

When I first heard about StackOverflow, and heard that it was being built in ASP.Net MVC, I was a little confused. I thought ASP.Net was always an example of an MVC architecture. You have the .aspx page that provides the view, the .aspx.vb page that provides the controller, and you can create another class to be the model. The process for using MVC in ASP.Net is described in this Microsoft article.
So my question is. What Does ASP.Net MVC provide that you wouldn't be able to do with regular ASP.Net (even as far back as ASP.Net 1.1)? It is just fancy URLs? Is it just for bragging rights for MS to be able to compare themselves with new technologies like Ruby On Rails, and say, "We can do that too"? Is there something more that ASP.Net MVC actually provides, rather than a couple extra templates in the File->New menu?
I'm probably sounding really skeptical and negative right now, so I'll just stop. But I really want to know what ASP.Net MVC actually provides. Also, if anybody can tell me why it's Model-View-Controller and not in order of the layers of View-Controller-Model or Model-Control-View depending on whether you are going top to bottom, or vice versa, I'd really appreciate that too.
EDIT
Also, it's probably worth pointing out that I've never really cared for the web forms (AKA server controls) model either. I've only used it minimally, and never on the job.
.aspx doesn't fulfill the MVC pattern because the aspx page (the 'view') is called before the code behind (the 'controller').
This means that the controller has a 'hard dependency' on the view, which is very much against MVC principles.
One of the core benefits of MVC is that it allows you to test your controller (which contains a lot of logic) without instantiating a real view. You simply can't do this in the .aspx world.
Testing the controller all by itself is much faster than having to instantiate an entire asp.net pipeline (application, request, response, view state, session state etc).
Scott Guthrie explained it in this post "ASP.NET MVC Framework"
It enables clean separation of concerns, testability, and TDD by
default. All core contracts within
the MVC framework are interface based
and easily mockable (it includes
interface based
IHttpRequest/IHttpResponse
intrinsics). You can unit test the
application without having to run the
Controllers within an ASP.NET process
(making unit testing fast). You can
use any unit testing framework you
want to-do this testing (including
NUnit, MBUnit, MS Test, etc).
It is highly extensible and pluggable. Everything in the MVC
framework is designed so that it can
be easily replaced/customized (for
example: you can optionally plug-in
your own view engine, routing policy,
parameter serialization, etc). It
also supports using existing
dependency injection and IOC container
models (Windsor, Spring.Net,
NHibernate, etc).
It includes a very powerful URL mapping component that enables you to
build applications with clean URLs.
URLs do not need to have extensions
within them, and are designed to
easily support SEO and REST-friendly
naming patterns. For example, I could
easily map the /products/edit/4 URL to
the "Edit" action of the
ProductsController class in my project
above, or map the
/Blogs/scottgu/10-10-2007/SomeTopic/
URL to a "DisplayPost" action of a
BlogEngineController class.
The MVC framework supports using the existing ASP.NET .ASPX, .ASCX, and
.Master markup files as "view
templates" (meaning you can easily use
existing ASP.NET features like nested
master pages, <%= %> snippets,
declarative server controls,
templates, data-binding, localization,
etc). It does not, however, use the
existing post-back model for
interactions back to the server.
Instead, you'll route all end-user
interactions to a Controller class
instead - which helps ensure clean
separation of concerns and testability
(it also means no viewstate or page
lifecycle with MVC based views).
The ASP.NET MVC framework fully supports existing ASP.NET features
like forms/windows authentication, URL
authorization, membership/roles,
output and data caching,
session/profile state management,
health monitoring, configuration
system, the provider architecture,
etc.
Primarily, it makes it very easy to create testable websites with well defined separations of responsibility. Its also much easier to create valid XHTML UIs using the new MVC framework.
I've used the 2nd CTP (I think they're on five now) to start work on a website and, having created a few web applications before, I have to say its hundreds of times better than using the server control model.
Server controls are fine when you don't know what you're doing. As you start to learn about how web applications should function, you start fighting them. Eventually, you have to write your own to get past the shortcomings of current controls. Its at this point where the MVC starts to shine. And that's not even considering the testability of your website...
No more auto-generated html IDs!!! Anyone doing any sort of javascript appreciates this fact.
ASP.Net with it's code behind is almost MVC - but not - the one big thing that makes it not is that the codebehinds are tied directly to the aspx's - which is a big component of MVC. If you are thinking of the codebehinds as the controller - the should be completely decoupled from the view. The new .NET MVC rounds this out - and brings a complete MVC framework. Though there are existing ones for .NET already (see Spring.NET).
I looked through a couple simple examples such as this one. I can kind of see the difference. However, I don't really see how MVC uncouples the view from the controller. The view still references stuff that's in the controller. I do see how it makes it much easier to test, and that at least in MVC the controller doesn't have any knowledge of the view. And you wouldn't have to process the view to call methods in the controller. I can see that's quite a leap, even though at first glance it may not seem like much.
I do agree with #Will about fighting server controls. I've never worked in a situation where they were actually used, but many people I know who have, have run into quite a few limitations with them.
Article about ASP.net MVC Vs ASP.net Web form
http://weblogs.asp.net/shijuvarghese/archive/2008/07/09/asp-net-mvc-vs-asp-net-web-form.aspx

Resources