ASP.NET MVC is heavily convention-based, "convention over configuration" as they say. So, this means there's a lot of significance to what name things are given and where in the project structure they are created.
As a newcomer to ASP.NET MVC, I appreciate the power and simplicity of this approach, but I do find it a bit confusing to keep track of what conventions are in play. For example, when using UpdateModel controller method, that relies on HTML form fields having the same names as the properties of the model class. That's the obvious thing to do and most of the time it's probably what most people would do instinctively, but I can see that it would get really confusing if one were to rename something in one place and forget to rename it in the other. The linkage is somewhat 'brittle'.
So, I thought it would be useful to have a list of all the ASP.NET MVC conventions here in one place, as short statements of best practice. things like:
"HTML Form fields should have the same name as Model Properties".
Anyone have anything like that? Will you help me create a list here?
Use the virtual path from your deployment server and enter it in the project configuration in Visual Studio. This way the visual studio development server will use the same path structure as the deployment server. This will save you countless hours of work when deploying.
Controllers should always end with the Controller sufix.
Note that convention over configuration is not required, but is how things work out-of-the-box. If you find a convention confusing or not helpful you can change it (eg. how controllers are picked, how views are located, etc.), or do configuration.
Controller and action names specified in routes should have corresponding classes and action methods named exactly this way (plus "-Controller" suffix for controllers). You can override this behavior using [ControllerName] and [ActionName] attributes.
Related
Hi there fellow Overflowing Stackers! Looking for your help in regards to having tiered or nested controllers in asp.net core
So far from what I can see, the default boilerplate code, and its default route {controller=Home}/{action=Index}/{id?} only allows for controllers to be in the default Controllers directory, which doesn't allow nesting at all.
From what I have seen thus far there are a few ways to get around this, neither which are ideal in my opinion.
Razor View Pages
Out of the box, it would appear that Razor Pages, automatically circumvent this issue as the .net core automatically attempts to traverse the corresponding folder structure from the associated URL structure to attempt to find a .cshtml file that matches the route.
The problem? This is more of an MVVM pattern than an MVC one. Which is the lesser of the 3 evils, in my opinion, (Open to debate ofc)
Route Attributes
The other alternative I see is that controllers can be associated with routes using the Route Attribute on Controllers and Actions [Route("parent/route/path")]
The problem? Same namespace (folder) means no reuse of Controller names and given the nature of our app, we need to namespace our Controllers. Not to mention that it's going to make the Controller Folder Massive, with 100's of Controller Files.
Adding More Routes
Adding more routes manually is going to be painful, as I have to add a new route for every possible permutation of parent and child within the folder structure.
Whilst I understand that this may be the intended way of doing things. Adding every possible nested folder in a new route is bad design in my opinion. As this is something that can automatically be inferred from the route to the folder structure. And is automatically done in other Languages and Frameworks automatically. (One excellent example C# Class Libraries)
Salt in the Wound
Most importantly it is apparently not possible to have the same named controller in two completely separate folders / routes:
How to use same controller name in different namespaces. When this happens you get greeted with an Exception AmbiguousActionException: Multiple actions matched.
The biggest pain point for me is that Namespaces are supported within the normal version of the .NET MVC Framework. For some wonderful reason, the namespace parameter has been removed from the MapRoute() method by someone at Microsoft. Scratching my head as to why that was done?
Not 'Just' a Rant
Before I continue, this post is not me whining or ranting, I am genuinely looking for a better solution and am looking for other ideas and alternatives. Please keep reading for my ideal solution below.
Ideal Solution
Since I have come from a PHP background I have found that simply using the default spl_register_autoloader() gave me exactly what I wanted. The capacity for me to register a specific namespace of my choosing and for PHP to look at any and all parts of the subsequent namespace in the local directory folder structure for the Controller I wanted.
i.e. the PHP controller Controllers\NestingLevel1\NestingLevel2\HomeController would look for the associated controller in Controllers\NestingLevel1\NestingLevel2\HomeController.php
Simple, Beautiful and Did I mention Simple?
Wrap Up
Is there any way I can get Nested Controllers in ASP.NET core without:
Razor View Pages (MVVM)
Route Attributes on Every Single Nested Controller
Manually Adding Routes for Every Possible Nested Parent / Child Combination
I come from an Asp.Net background and I'm evaluating Asp.Net MVC for a new project. I can't see how to structure a large project adequately.
I'm happy with the Model/View/Controller architecture and I'm presently trying to get Areas to work (which seems quite complicated for what it is).
Can you have Areas within Areas?
Can you put Views in dlls?
I really need a starting point here, are there are resources which show how to structure large MVC projects, assume that eventually there will be 100+ views in the project, I don't want them all in the same folder and ideally I'd like sub folders
thanks for any help
Edit:
I can see that each controller maps to a View folder, what I want is something more like this
Areas
Mail
Absence
SimpleAbsenceController.cs
ComplexAbsenceController.cs
Overtime
SimpleOvertimeController.cs
ComplexOvertimeController.cs
Etc
Edit2: Perhaps this is more of a routing question, can I map from:
http://www.mystuff.com/SimpleAbsence/Index
to Mail/Absence/SimpleAbsenceController
Fundamentally I want a way of structuring my project into folders
I hate answering my own question as I feel it undermines the work of others who try to help, at the same time others may look at this later and these really are newbie questions, so...
(this is all from reading Pro ASP.Net MVC5, good book)
I wanted to know how much flexibility there is in Asp.Net MVC with regard to using subfolders or dlls. This answer address the subfolders question.
Answers
You can put controllers where-ever you like in terms of folders on the disk, these are compiled, but...
When you use areas the MapRoute in the AreaRegistration.cs file automatically limits
the routes to the namespace for the area. So if for example you move a controller to an area you -must- change the namespace or methods like Url.Action will fail
Views must stay where they are, so for a controller called Fred there must be this structure:
View
- Fred
- Action1
- Action2
- etc
You can work around all of this using your own routing system, you could probably work around the namespace issue with a custom route, but my view is as a newbie you should work with the system until you know enough to fully understand the consequences of breaking the rules
So this means you could have a large project with a few hundred Views all lumped together in one folder. It's not quite as bad as it seems as the controllers can be in sub folders and you can directly map from them to the Views.
You also have flexibility in the routing system, so regardless where controller are on disk you can have any urls you like!
e.g. this route maps from
http://www.example.com/App/DoSomething to
http://www.example.com/Home/Something with no changes necessary
routes.MapRoute("NewRoute", "App/Do{action}", new { controller = "Home" });
NB If you do this make sure to use Html.ActionLink or Url.Action (or equivilents) as opposed to direct links, these are clever enough to generate the correct urls based on the routing.
As I say, complete newbie issues but I'm sure others will have the same questions, thanks to MiniRagnarok for his example of a real life project
What we're talking about here is very opinion based. I've seen people that prefer to have lots of Controllers with a mapping of every object to a Controller. I've also seen people that prefer to have tons of Views. So my example is what our team has decided to do and not necessarily the same as you would see in sample tutorials.
Take a project we did that has 200+ Views for example. The site is an auction and retail site.
Controllers
AccountController.cs
AdminController.cs
AuctionController.cs
HomeController.cs
PhotoController.cs
StoreController.cs
SupportController.cs
Views
Account
DisplayTemplates
EditorTemplates
ChangePassword.cshtml
_Favorites.cshtml
Settings.cshtml
Admin
Auction
Home
Photo
Shared
Store
Support
For us, we name all partial views with an underscore first. We also utilize DisplayTemplates and EditorTemplates. All of this really helps us keep things separate. You'll notice that our controllers are split by role or function. We were never bothered by the fact that there are many ActionResults within our controller since all of our logic is really in the models.
Is there any functional reason of the default files structure on new ASP.Net MVC Application (Grouped by controllers, model, views etc. ?
Otherwise I would structure it in a way that would be more convenient for me.
Thanks!
Technically, you can put models and Controllers anywhere, since they're just code files that get compiled into a DLL. Other files, however, have stricter location requirements if you want to take advantage of the conventions that MVC asssumes.
Strictly speaking, you can place views anywhere. However, doing so has a number of consequences. You must specify the full path to the view in your View() method, and if you don't put views in the ~Views folder, then it's possible for people to download them directly (which you don't want).
In general, MVC works a lot more smoothly if you follow the conventions. If you go your own way, you lose a lot of automation and productivity.
I'm currently working on an asp.net-mvc content management system. It would be incredibly useful to be able to deploy nested applications e.g. /shop to have a separate app inside. Or even another instance of the cms.
I've found some information around talking about limiting the inheritance of the web.config but I've no idea how this maps to an MVC application. I'm hoping as its essentially the same stack it will just run. Nothing is ever that easy though.
If anyone has any experience doing this I would be really grateful. The idea of one big application to rule them all is not at all nice.
Si.
To be honest you biggest hurdle is going to be creating the routes and making sure they don't interfere with routes already in the system. After you get that working the rest is easy as pie.
The first thing you will need is an HttpModule that will be inserted in to the web.config under the . This module will be used to register and custom ViewEngines or Routes that you want to register. You do this in the same way that you do in the Global.asax but instead of putting them in the Application_Start you put them in the static constructor of the HttpModule. This is so they are only loaded once like Application_Start.
By do the above you will have created a module that is easily transportable and doesn't require the implimentor to modify their Global.asax code to get your stuff to work.
The second thing you probably want to do is create a custom configuration in the web.config to set stuff like the root path of your application. This will be prepended on to the route when you are setting it up in the HttpModule. Also you can use this to store customization information that is not appropriate for the database.
Last but not necessary is that you may want to create a custom ViewEngine that knowns and understands your folder structure. This is only necessary if you want to store the views in a different path than the default views, in order to minimize conflicts.
Check out the Grouping Controllers with ASP.NET MVC from Phil Haack.
Hope it helps,
Bruno Figueiredo
I've gone down this road before (with /blog), but found it to be doable but complicated and difficult to maintain. Instead I ended up using subdomains:
www.example.com
shop.example.com
blog.example.com
These are much easier to maintain because you can just have them work as separate websites in IIS. And, of course, you can always redirect www.example.com/shop to shop.example.com.
What is the purpose of the code behind view file in ASP.NET MVC besides setting of the generic parameter of ViewPage ?
Here's my list of reasons why code-behind can be useful taken from my own post. I'm sure there are many more.
Databinding legacy ASP.NET controls - if an alternative is not available or a temporary solution is needed.
View logic that requires recursion to create some kind of nested or hierarchical HTML.
View logic that uses temporary variables. I refuse to define local variables in my tag soup! I'd want them as properties on the view class at the very least.
Logic that is specific only to one view or model and does not belong to an HtmlHelper. As a side note I don't think an HtmlHelper should know about any 'Model' classes. Its fine if it knows about the classes defined inside a model (such as IEnumerable, but I dont think for instance you should ever have an HtmlHelper that takes a ProductModel.
HtmlHelper methods end up becoming visible from ALL your views when you type Html+dot and i really want to minimize this list as much as possible.
What if I want to write code that uses HtmlGenericControl and other classes in that namespace to generate my HTML in an object oriented way (or I have existing code that does that that I want to port).
What if I'm planning on using a different view engine in future. I might want to keep some of the logic aside from the tag soup to make it easier to reuse later.
What if I want to be able to rename my Model classes and have it automatically refactor my view without having to go to the view.aspx and change the class name.
What if I'm coordinating with an HTML designer who I don't trust to not mess up the 'tag soup' and want to write anythin beyond very basic looping in the .aspx.cs file.
If you want to sort the data based upon the view's default sort option. I really dont think the controller should be sorting data for you if you have multiple sorting options accessible only from the view.
You actually want to debug the view logic in code that actuallky looks like .cs and not HTML.
You want to write code that may be factored out later and reused elsewhere - you're just not sure yet.
You want to prototype what may become a new HtmlHelper but you haven't yet decided whether its generic enough or not to warrant creating an HtmlHelper. (basically same as previous point)
You want to create a helper method to render a partial view, but need to create a model for it by plucking data out of the main page's view and creating a model for the partial control which is based on the current loop iteration.
You believe that programming complex logic IN A SINGLE FUNCTION is an out of date and unmaintainable practice.
You did it before RC1 and didn't run into any problems !!
Yes! Some views should not need codebehind at all.
Yes! It sucks to get a stupid .designer file created in addition to .cs file.
Yes! Its kind of annoying to get those little + signs next to each view.
BUT - It's really not that hard to NOT put data access logic in the code-behind.
They are most certainly NOT evil.
Ultimately, the question you ask yourself is this:
Does this code A) Process, store, retrieve, perform operations on or analyze the data, or B) Help to display the data?
If the answer is A, it belongs in your controller. If the answer is B, then it belongs in the view.
If B, it ultimately becomes a question of style. If you have some rather long conditional operations for trying to figure out if you display something to the user, then you might hide those conditional operations in the code behind in a Property. Otherwise, it seems like most people drop the code in-line to the front end using the <% %> and <%= %> tags.
Originally, I put all my display logic inside the <% %> tags. But recently I've taken to putting anything messy (such as a lengthy conditional) in my code behind to keep my XHML clean. The trick here is discipline - it's all too tempting to start writing business logic in the code behind, which is exactly what you should not be doing in MVC.
If you're trying to move from traditional ASP.NET to ASP.NET MVC, you might aviod the code behinds until you have a feel for the practices (though it still doesn't stop you from putting business logic inside the <% %>.
There isn't a purpose. Just don't use it except for setting the model
ViewPage<Model>
See this blogpost for more info.
At this Blogpost is a working example of removing the code behind.
The only problem I'm stuck with is that it is not able to set namespaces on the class.
The codebehind provides some of the strong typing as well as the intellisense support that you get in the view. If you don't care about any of these two features, you can remove it.
For example, I typically use the NVelocity ViewEngine because it's clean and pretty straight forward.
This is a great question. Doesn't MVC exist in the ASP.NET environment, without using the specific MVC pattern.
View = aspx
Controller = aspx.cs (codebehind)
Model = POCO (Plain Old C#/VB/.NET objects)
I'm wondering why the added functionality of MVC framework is helpful. I worked significantly with Java nd MVC and Java Struts several years ago (2001), and found the concepts in MVC to be a solution for the Internet Application organization and development problems at that time, but then found that the codebehind simplified the controller concept and was quicker to develop and communicate to others. I am sure others disagree with me, and I am open to other ideas. The biggest value I see to MVC is the front controller pattern for Internet development, single entry source for Internet Application. But, on the other hand, that pattern is fairly simple to implement with current ASP.NET technologies. I have heard others say that Unit Testing is the reasoning. I can understand that also, we used JUnit with our MVC framework in 2001; but I have not been convinced that it simplifies testing to use te MVC framework.
Thanks for reading!