Organizing Areas in ASP.Net MVC 5 - asp.net-mvc

Get ready for yet another elementary question from me...I think I have a grasp on the Area concept in a MVC site, but I would like to organize them even further, could I either move them to an external project (with controllers, views, scripts, styles) or create sub-folders within the Area folder?
Reason I'm asking is that I have tried to create a folder under Areas and called it Common, then created an area inside that folder and called it MyTest. When I attempt to browse to mysite.com/mytest, it fails.

You should try to go the usual way and use areas as a subfolder of the Areas ASP.NET root folder. The only reason why your URL would fail is that your AreaRegistration file is not properly registering your route. You can check out Glimpse as a way to debug routes or simply look at the files and try to figure it out your self. Keep in mind that ASP.NET automatically look for classes that inherit from AreaRegistration and use them to register routes that are specific to your area. If your routes seem to be configured properly, make sure your controllers are in namespaces that are visible to the route.
If you want to isolate the areas (with the controllers models and views) into separate projets, you should look into creating your own VirtualPathProvider, because that's the only way for your views to be located. However, they would have to be Embedded Resource and couldn't be debuuged. Your area, if located in a separate DLL, would be automatically registered and your controllers would be automatically found as long as the DLL is in the main application Bin folder.

Related

Asp.net MVC 5 separate projects for UI and Web

How can I go about separating my MVC project into UI specific (JS, CSS, Images, Fonts, and maybe Views) and Controller/Model specific (Controllers, Helpers, Models, and may be Views). Since our front-end developers work mostly independent of Visual Studio, I was looking for best practices in separating projects. Any pointers or sample projects?
This is how we finally ended up doing it.
Create a separate visual studio project called SolutionName.Client (this is where all frontend js and scss files go)
Create you MVC project called SolutionName.MVC (this is the asp.net mvc project)
Using Grunt.JS write tasks that compiles all js and css files and drops them to SoltuionName.MVC/Content folder
Similarly write tasks that drops all Views (razor files) into SolutionName.MVC/Views folder.
In Project build settings, add a pre-build tasks to run grunt task.
This setup took few hours to get it working but it is now quite useful.
You can easily do this and I've done it for each of my projects in MVC as well.
One project has your Controllers, ViewModels, and in my case, any custom logic related to Dependency Resolution for MVC and custom classes related to security authentication with MVC. Basically any code that touches the MVC framework core and is not involved in rendering content.
The other one has pretty much everything that you use on the client-side, and code needed for the front end. Which in my case, code-wise, is very minimalist and included some code for Glimpse and Elmah. The rest is your Views, Styles, Scripts, static content like downloads, etc.
As for the files in App_Start, My views project has Bundles, Filters, and obviously any HtmlHelpers you may have, custom css transformationslike for LESS.
My Controller's App_Start has the RouteConfig. These aren't necessarily critical it's just the way I ended up organizing mine and really depends what aspects you need access to during the startup of those components.
I will say that to save yourself time, in your Views/web.config file, add a namespace entry for your Company.Project.ViewModels namespace so that it's done in one place and you don't have to add it to each view, as this namespace would reside in your Controllers Project.
Your project with the Views will be your startup project. Just make sure in the global.asax your calls to the FilterConfig, RouteConfig and BundleConfig all resolve correctly.
It's fairly easy to do, my recommendation is to try it yourself and split it out the way you want and if you have problems come back and ask about the difficulties rather than looking for a step by step guide.
Bottom line is, yes it's possible and yes it works,

MVC Web Api - barebones minimal project structure

I'm looking at this MVC WebApi starter kit (for Angular/TypeScript)
Ignoring all the client side code, I noticed the author has made a WebApi that is extremely bare bones. Has has taken out most scaffolding including _ViewStart.cshtml, _Layout.cshtml, and forgoed the convention of controllers in Controllers folder and views in View folder under subdirectory with same name of controller, etc.
He added some interesting Routing and Validation classes that I havent seen before in a Core folder and put controllers in Api folder and Views directly into Views folder with an Index.cshtml at the root.
It's very clean and barebone project structure for a standalone web api that will do nothing except serve data to a client heavy application. I kind of like it this way but before jumping ship I'm wondering what drawbacks this approach has and if I'm actually giving up any core features of the framework by doing it this way. For example, clearly MVC Areas are being given up here in favor of flexibility to create your own view folders structure and seperation of application sections (I'm okay with getting rid of MVC Areas I rarely used them anyways). Another thing is I don't think a Controller action method can return View() and it will find it in the Views folder by convention of the controller name. I'm also okay with that since I will only be serving JSON data and will use 100% client side templating.
Are there any other core features that are being abandoned that I'm missing that may make me regret going with this project structure?
When I create Web APIs that are hosted in IIS, the only files in my web application are web.config, global.asax and global.asax.cs. Everything else is not required.
Take a look at this template if you haven't already before you decide how to structure your ASP.Net MVC / Angular project:
http://visualstudiogallery.msdn.microsoft.com/5af151b2-9ed2-4809-bfe8-27566bfe7d83
You can always add components into your project later, so I wouldn't seat it too much. I like to start with a lean/mostly empty project first and add things myself so that I fully understand what I'm adding.

ASP.NET MVC: Grouping classes around controller

In asp.net mvc (4), out of the box, views go into Views folder, and then grouped by controller in subfolders.
Controllers go into Controllers folder, (View/Edit/Input)Models go into Models folder, etc.
I do like the way views are organized. I do not, however, like breaking the rest of the MVC pieces horizontally.
My question is, what would be downsides of leaving views organization structure as it is, but group other classes by controller (i.e. by use-cases). E.g.:
/Home
HomeController.cs
IndexViewModel.cs
IndexViewModelBinder.cs
/Messages
MessagesController.cs
MessagesApiController.cs
MessagesViewModelBinder.cs
MessageViewModel.cs
MessagesListViewModel.cs
/Views
/Home
Index.cshtml
/Messages
MessagesIndex.cshtml
MessageDetails.cshtml
All that matters is the arrangement of the View files because they're accessed at runtime. Everything else is compiled into the assembly so the physical location of their source files is irrelevant.
Like you I find the default arrangement a bit awkward for larger projects, so this is how I lay out my current projects:
~/
/Areas
/DefaultArea // I always use areas, even when there's only one, because it simplifies things when adding additional areas.
/Controllers
FooController.cs
/Views
/Foo
FooView.aspx // Yes, I use WebFormView. Just a matter of personal preference
FooEdit.aspx
FooModels.cs // this file contains my ViewModels
So basically, I put my ViewModel classes in the same folder as the views rather than putting all the ViewModels together (which makes less logical sense). I was tempted to put my Controllers in their views' folders, but I decided against it.
I've found no downsides to my approach so far (been using it almost 2 years now).
I generally like to avoid areas where possible as it creates some issues with routing.
I think your structure is completely fine (and superior to the default MVC/Web structure of separating code based on "type" rather thank "function").
All I would suggest is that you only keep your "web" .cs files in the web DLL (e.g. Controllers, ViewModels, Binders, etc) and have the same structure in separate DLL(s) for Domain / Services / etc layers so they can be reused / tested separately if/as required.

How to seperate MVC project to several smaller MVC projects

I have an MVC 3 app that has some core functionality (most important is autorisation) but mainly serves as a portal to different areas or modules. I want to organize thit to different modules that with minor changes also can be deployed as their own website.
The project consists of a Forum, Blog engine, Messaging between users + 4-5 upcoming modules.
I looked at ScottGu's blog about MVC 2 and found something that seemed perfect:
Depending og what the customer need I want to only give them the exact modules they can use. It is also easier from a maintainence view to be able to work and update referencd assemblies in each project and just do a full update for the customers that have that spesific module on their server.
But in MVC 3 there is no apparent way to use Areas this way, do you know how?
Status
I will try to add MVCContrib Portable areas to my existing solution and convert my areas ower and will post back the results. If it works I will mark it as the accepted solution.
MVCContrib has portable areas.
http://mvccontrib.codeplex.com/wikipage?title=Creating%20a%20Portable%20Area&referringTitle=Documentation
This is possible in MVC3:
From:
http://bob.archer.net/content/aspnet-mvc3-areas-separate-projects
Right click on the shell project and "Add Area...". Type in the area name. This will create an Areas folder with your area in it. (This is not 100% needed but you do need the "Areas" folder and you can steal the XXXXAreaRegistration class for your application.)
Create a new MVC3 empty project in your solution to match your area. Move the XXXXAreaRegistration.cs file from the shell mvc project to the new project and adjust the namespace as applicable. (Or you can manually create an area registration class, it's a pretty simple class. Just use the Add area template generated one as an example.)
Edit the routes in the AreaRegistration folder as needed.
Delete the folder under the areas folder that the template wizard added.
Modify the web.config of the new project and take out the connection strings and the authentication, membership, profile, rolemanger sections. You will not need to deploy this web.config but the razor intellisense doesn't work without it during dev time.
Delete the global.asax file from the area's project or you will get extra default routes.
Create a virtual directory in the "Areas" folder of the shell project with the name of your area as the alias and point it to your "area" project. You will need to use IIS or IIS Express for this. I use IIS. For IIS Express you can use the appcmd.exe in the IIS Express folder or you can edit the applciationhost.config file.

Render View (or Partial) In another project?

i have a solution with the following two projects - MyNamespace.Services and MyNamespace.Web.
Web contains a MVC web application.
In the Service project i have a EmailService class that takes care of sending out emails to the user.
I want to use either a partial or a view (ascx or aspx) for email templates.
I have found several solutions on how to render a partial view and get the result as a string which works fine if the template is inside the web project (as it is a controller in the web project that calls the email service).
(the 2 methods i am trying to use is either http://developersisland.blogspot.com/2009/01/renderpartial-to-string-in-aspnet-mvc.html (at the bottom of the blog) or http://www.brightmix.com/blog/how-to-renderpartial-to-string-in-asp-net-mvc/)
But my email templates are located in the Services project.
How can i refference the path to the templates (partial/view) in my Service project from inside the Web project, that works with either LoadControl or RenderPartial which both takes a virtual path as a parameter ?
It seems like no matter what i do the root directory is set to the Web projects directory.
Is it possible ?
Would be nice to be able to make it work independently of the web project somehow.
I don't think this is possible without developing your own view engine. The default view engine will only look in certain locations for the partial view -- which includes the current view folder and the shared views folder. I don't think you can search for views outside the current project since those views aren't registered with the view engine.
You can consider just creating your HTML helpers to render emails and return it as a string.
Doesn't really matter whether it is partial view or a method returning a string with HTML. i actually think that for your case helper methods would be a better choice.
A simple helper method is also more flexible in the ways you can use it.
You could try creating a custom view engine locator or virtual path provider. Here are a few examples that may help you get going:
Views in seperate assemblies in ASP.NET MVC
Grouping Controllers with ASP.NET MVC
How to use virtual path providers to dynamically load and compile content from virtual paths in ASP.NET 2.0
All of the links above are good, this might help as well. you will certainly be able to get it to find and use the views. The problem I had was in working with them, there was no code completion etc in the other projects. It was semi possible to get that as well by fiddling around with the project file but to be honest I ended up going with the Grouping solution above
Plug in architecture for ASP.NET MVC

Resources