I would like to create a sub folder in the controllers folder of an Asp.Net MVC application. But when ever I do this and try to navigate to a page the controller can not be found.
Here's a concrete example.
Currently I have:
Controlers/UserAdminControler.cs
Controlers/PageAdminControler.cs
Controlers/MenuAdminControler.cs
Controlers/SomeOtherControler.cs
...
I want to organize it like this:
Controlers/Admin/UserAdminControler.cs
Controlers/Admin/PageAdminControler.cs
Controlers/Admin/MenuAdminControler.cs
Controlers/SomeOtherControler.cs
...
I found a way to create "Areas." This is a really nice idea and article but that is not really what I am looking for my site:
http://haacked.com/archive/2008/11/04/areas-in-aspnetmvc.aspx
As well I have found that you can create sub folders in the Views directory (when you return View() you simply supply the path as a parameter). All I need now is to figure out how to add sub folders in the controllers directory.
I just tried it, with no issues. I added a sub folder in my Controllers direcotry, and called it "SubFolder". There I added a Controller called "SubController". I then added a Folder in my views called Sub and added a View called Index. I then ran the app and navigated to:
http://localhost:2922/Sub/Index
with no problems. Maybe I'm misunderstanding your question, but there seems to be no issues with adding subfolders in the controllers folder.
Take a look at S#arp Architecture. Billy has baked in the concept of areas already. You can find the information here: http://code.google.com/p/sharp-architecture/. You can also find the information to the google group there as well. It is very active and very supportive.
Related
I know how to customize a controller/view template for an MVC project. However, I have a few different MVC 3 Areas in my project and each Area has its own Models, Views and Controllers. Is there a way to specify different code templates for each Area? I tried to place a CodeTemplates folder in one of my Area sub folders but it didn't work.
The idea is, when I right click on any Controller folder in an Area and select Add -> Controller, I want it to use that Area controller template.
UPDATE:
I will be happy with being able to select the controller template I want to use, but still wondering if it is possible to specify CodeTemplates for the different areas.
Looks like MVC Scaffolding might be my only option here. I will show specific solution when I get it working.
Rereading you question, I realized my answer may not be what you are trying to do. Do you wan't the auto generated code in the view to use a different template? Or did you wan't the page to look differently, like with css changes, etc? My answer applies to the latter. If you want to use different code templates, it seems like (according to this) as long as you give them different names you should be able to select the one you wan't to use. You could also probably just remove the ones you don't want from the project then add them back later.
Create 2 files in the folder you want the template to be applied to, one named _ViewStart.cshtml and the other _Layout.cshtml
In the _ViewStart file, add this:
#{
Layout = "~/Views/Reports/_Layout.cshtml";
}
This will point to the _Layout so change the path as needed. In the _Layout file add whatever you want, just like the layout in the Shared directory. And for any other folder you want to use this layout, just add the _ViewStart file to that directory and point it to the _Layout file you want.
I am using Asp.Net MVC 3.0 and I have my _layout.cshtml in Shared folder. Problem is I want to generate menus in this .cshtml which should be loaded from database. But as I understand _layout.cshtml won't have any action etc associated where I can write logic and I don't want to write all this code in cshtml itself. Are there any options to write logic for cshtml within Shared folder?
You can setup a Controller and a view to render the menu and call it inside the _layout.cshtml.
#{ Html.RenderAction("Index", "Menus"); }
Eranga is correct, but let me expand on his answer, to answer your question specifically.
What you can do is create a new controller ("menus" for example), and create an action called default. Have this action return a view, calling it whatever you would like. Now go to your shared folder and add the view using the name you just specified.
Now for the cool part. By default, the MVC framework will look in the controllername/viewname path first, and if it fails it will then look at your shared/viewname path, which is where the view you just created resides! Neat, huh? ;p
Check out http://www.aspnetmvcninja.com/views/view-search-paths for more info on MVC search paths.
#Eranga has given you a good head start on implementing the feature you requested. I think the below two articles will be helpful as well:
Html.RenderAction and Html.Action:
http://haacked.com/archive/2009/11/18/aspnetmvc2-render-action.aspx
A sample implementation of Html.Action method with caching:
http://www.tugberkugurlu.com/archive/donut-hole-caching-in-asp-net-mvc-by-using-child-actions-and-outputcacheattribute
We have a fairly large MVC project with a large number of views and partial views (display/editor templates). Pretty much 95% of our UI is in our templates, our aspx views are just placeholders that call our ascx templates. As such, whenever we open that Views folder in VS2010, it's fairly painful to scroll down to the Shared folder for us to manage our templates.
We'd LIKE to change this hierarchy just a bit. Instead of having a folder for each controller under Views, instead we'd like to have a folder called Pages under Views and have our per-controller folders under here. This way, when we open Views we have 2 folders: Pages and Shared.
Is this easily possible without going back and editing every single one of our controllers where they simply return View(); to return View("Pages/MyControllerName/MyActionHandler");? I'd like the controllers to still simply return View(); and without my URLs changing. So in other words, I just want to move my root directory for my Views into Views/Pages, but not for templates - they stay as they are.
Solution we went with:
global.asax.cs: (add these as the first 2 lines of Application_Start() - change nothing else)
var locations = ((WebFormViewEngine)ViewEngines.Engines.First()).ViewLocationFormats.ToList().Select(x => x.ToLower().Replace("views/{", "Views/Pages/{"));
((WebFormViewEngine) ViewEngines.Engines.First()).ViewLocationFormats = locations.ToArray();
This allows our Views folder to have 3 things in it:
Pages
Shared
web.config
Since we do 95% of our UI work within our Shared DisplayTemplates and EditorTemplates, this rmeoves the mostly-ignorable stuff from being in-our-face all the time as developers. While the suggested answer was to do ViewEngines.Engines.Clear(); and then add a newly-instantiated one, we had problems with MVC playing nice with the new one. So we chose to instead alter the functional and already-instantiated instance. I don't like the casting, and we'll put some code around that to be better, but this is the functional code to get anybody started that also wants to do this.
You need to register a ViewEngine with the ViewLocationFormats property set to include your new locations.
I have searched on Google (may be with wrong keyword) and visited the tutorials of ASP.NET/MVC website. But didn't understand the routing of MVC properly.
I have a scenario of the following figure. I want to display the Index.cshtml when the website lunched.
I have changed the RegisterRoutes method of Global.asax.cs file in various ways. The latest code (not working) is below
routes.MapRoute(
"App", // Route name
"App/{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
I will be very happy if someone explains the MapRoute method with different example along with answering my problem.
I don't think the problem is with your routes, I believe it is caused by moving your View and Controller folders to the App folder.
MVC use "convention over configuration" for stuff like where the folders are located, I'm guessing it can't find the Views/Controllers in the new folders?
From here:
These folders are included even in an
Empty ASP.NET MVC application because
the ASP.NET MVC framework by default
uses a “convention over configuration”
approach and makes some default
assumptions based on folder naming
conventions. For instance, controllers
look for views in the Views folder by
default without you having to
explicitly specify this in your code.
Sticking with the default conventions
reduces the amount of code you need to
write, and can also make it easier for
other developers to understand your
project.
I'm not saying that it's not possible to have a folder structure like you have, I just dont believe its supported out of the box.
Personally I'd recommend moving back to the default, if you need to keep this structure then I think you may need to implement your own ControllerFactory and ViewEngine (I'm not sure if these are the correct hooks that you would need to change).
Edit:
Are you trying to implement App as an Area?
Edit2:
If you are trying to add App as an area there are some steps you will need to follow, The reason I wasn't sure if this was what you were trying to do is because I thought areas had to exist within an Areas folder.
There are some steps outlines here Including how to register your area if that is what you are trying to do.
ASP.NET MVC 3 has a built in feature for sub folders. That is called Areas (thanks #Morten for let me know the word). But after finishing the MSDN Walkthrough for Areas, I was still unable to run the web application. The error was showing Configuration errors. #Danny also noticed that.
Then I searched and found that, the Web.config files in the sub folders shouldn't contain application specific properties.So, I removed those properties from the Web.config files. Then I was able to run. But there were some runtime errors when I wanted to navigate to my sub folder/area views. The error was "Could not load type ‘System.Web.Mvc.ViewPage<..<>’" when I click on the links for the views of the Areas folder.
Then I again searched and found helpful this post. And then my application successfully run and I can navigate all of the pages.
I'm having a ASP.NET MVC 2 Project where I'm making some management system... The thing is that I have 4-5 controllers that are all related to a specific thing in the management system and having 4-5 diffrent view folders dosent make it any easier.. Any suggestions? Since its "a part" of the management system I dont really see how I can make use of areas. All ideas welcome.
UPDATE:
For example I have a thing in my management system called "Product Management", this thing have following controllers attached:
CategoriesController =
Add/Delete/Edit categories.
ProductsController = Add/Delete/Edit
products in categories.
OrdersController = Add/Delete/Edit
orders from users.
Seems like a waste that I need to create 3 diffrent view folders for those controllers.. Would be much easier if I could create a folder under the "Views" named "Product Management" and then just create a sub folder for each controller...
I don't think you can arrange it that way.
You can create an Area as ProductManagement and have your controllers/views inside it.
You can keep the pages under Shared folder, so that they can be picked up by View engine can find and render the page.
If this is not the solution you are looking at, can you please elaborate your problem further?