Adding a view to MVC that doesn't belong to a controller - asp.net-mvc-3

I'm not sure if the question title really explains what I want to do, however I will explain below:
I am using the Visual Studio MVC project template and I have changed some of the tabs to map to different actions from different controllers. However I want to make one of the tabs to open a view that will again have links for different administration actions.
The problem I have is that I am unsure where to place this view as it doesn't really belong to an admin controller as each tab on this view will link to a list view in another controller. In effect it is a sub _Layout view, as it doesn't have anything to do with a controller.
I hope I have made myself clear enough!

You can place this view in the Shared folder since it will be used by multiple controllers. Or, you could place it somewhere else and reference it by using the full path to this View/Partial View
In a Controller
public ActionResult SomeAction(){
return View("~/Path/To/View/ViewName.cshtml");
}
In a View (Razor)
#Html.RenderPartial("~/Path/To/View/ViewName.cshtml");
With that said, the Shared folder makes the most sense since it will be shared across multiple controllers.

Related

Return View From Controller in Area Not Working

After reading several posts on this subject I have yet to find an answer to my problem. I have an MVC 3 application and have added an Area to it. Everything works great until I try an return a view from a controller within the Area.
I can successfully post to the controllers Save Method but upon simply returning the view (return View()) I get the following:
The view 'Save' or its master was not found or no view engine supports the searched locations. The following locations were searched:
~/Areas/Test/Views/Default1/Save.aspx
~/Areas/Test/Views/Default1/Save.ascx
~/Areas/Test/Views/Shared/Save.aspx
~/Areas/Test/Views/Shared/Save.ascx
...
This seems so basic, not sure why I am running into so much trouble.
Ive used Phil Haack's RouteDebugger (http://nuget.org/packages/routedebugger) and all routes are working as setup...
MVC is expecting (by the convention) a view (with the same name as your action name in any one of the folders (by default, But you can override this). You should have the view in any of the folders. That is the MVC convention. So add your view to that folder. You can add it by right clicking the Return View() statmenet in your action method and selecting Add View option. It will automatically add one view.
Or you can right click on the Areas/Test/Views/Default1 folder and select Add View and save it with the same name as of your Action method. If you want to save it with a differnt name than the action name, you can use the View method like this
return View("MyOtherViewName");
Assuming that you added a MyOtherViewName.cshtml as your View in the Areas/Test/Views/Default1 folder

In a single page desktop-like application, should I dynamically instanciate a controller for a window? How?

I'm asking this because I really don't know where I should handle events of my dynamically created window.
When someone clicks on a desktop icon, the window (if it doesn't exist) will be dynamically created. Should I create a controller when creating the window and hook to it? If yes, how?
Here you can read different approaches I've thought about:
Create a controller that will instanciate the Window (as its view), I will handle everything there
Create the window only and hook everything in my taskbar controller (which is where the window is created). In this case, the Taskbar controller will become very big.
Pre-create all window controllers and eventually windows too and hide them (when page is ready). Then just show/hide them, so I will have "static" references to all controllers with getController in Application
Which approach should I use?
Edit 1:
I'm trying to dynamically instanciate (and reference it through another controller) a controller. I'm having hard time expecially in referencing it. Any suggestion on how it should be done?
I found Ext's MVC unusable with desktop demo as it's possible to have multiple windows (views) of the same type tied to a single controller. Each window has it's own state and it's hard to differentiate between the views in the controller.
I solved the problem by myself: I preinstanciate the controller as I do with all controllers, by inserting them in Application controllers array. After this, I instanciate the view on that controller when a method is called, then I simply use refs to access this view.
The method is quite clean and using refs feel so good. Obviusly the controller has a method hasWindow which checks if the controller view has been created already.

mvc 3 razor view engine using "default" views

i'm using Razor for a new project in my company, and i have been playing with it for 2 days and already found some weird behaviour imho.
I have a home controller in the root of my webapp and a home controller in an area , call it Area1. In both these controllers I have an Index action and therefore I got an Index view in the Views root folder, and another one in the Area1\Views folder. If I remove the index view within the area , so Area1\Views\Index.cshtml and I request Area1\Home\Index, I don't get an error about the view engine not finding the view for that action , but the "base" Index view is found in \Views\Index.cshtml and rendered.
Someone knows if this is a bug or it's done by purpose ? If so, there's any way to disable this default ?
Definitely NOT a bug.
This behaviour allows easy reuse of View templates, eg, for error handling.
The default behaviour for ASP.NET MVC is that if you do...:
return View();
...it searches for the view template with the name of the action to use in a number of places: the default naming convention folder for the controller, ie, /Area1/Views/Home/, then /Area1/Views/Shared/ then Area1/Views/ then /Views/Shared/ then /Views/
If it finds no such View matching the name of the action, then it throws an error.
So much for the default behaviour. To "customize" this behaviour, you just need to do the following:
In your controller actions, you can specify the name of the View template to use when you return. EG:
return View("MyOtherView");
or better still, if using T4MVC:
return View(MVC.Area1.Home.Views.MyOtherView); // does away with "magic" strings
As a result, I don't see that you need to switch off the default behaviour to be able to do (whatever) you want. Controllers are there to, uhmmmm, control what views are used to display to the user. That is the best practice.
However, ASP.NET MVC is very configurable, so there are ways and means, I presume, to switch this off.
If you want to do this, good luck to you, but it makes much more sense to follow the defaults and get to understand how ASP.NET MVC works, especially if you are a beginner.
NOTE:
The above applies to ASP.NET MVC 1, 2, 3 and will continue to do so. It is the default behaviour for all View engines, including Razor and WebForm Views.
PS:
And you can configure the urls using route registration if your concern is the look of the url in the user's browser.

How to specify default LayoutPage in Razor in ASP.NET MVC 3 Preview 1?

I want to specify (in one place) a default layout page in Razor, so that I can delete this:
#{ LayoutPage = "~/Views/Shared/_Layout.cshtml"; }
from every .cshtml file I have. But I don't know how... Any ideas? I'm using Razor engine from ASP.NET MVC 3 Preview 1.
Create a "~/Views/_ViewStart.cshtml" page and the following inside:
#{
Layout = "~/Views/Shared/_Layout.cshtml";
}
Note that you can write code in here, so it is possible to change your layout based on the type of device targeted, etc.
This is now created by default in an empty MVC3 project.
Source
It looks like the way to do this is by using a _init.cshtml file in the root of the view directory in which you would like a common page element (header). When the Razor view engine builds your page it looks for a few specific files automatically called _start.cshtml, _init.cshtml, and _end.cshtml; these files are loaded in respective order by the view engine for every request. Placing the LayoutPage definition, and/or other common initialization operations in these files will ensure they're run for all pages.
Note: I'm not sure if the effect is passed down into sub-directories as it wasn't clear from the documentation; you'll have to give it a try and find out.
There's quite a bit more detailed information on how to do this found in the Microsoft how-to book on building pages with Razor. I found the section Running Code Before and After Files in a Folder on page 169. Check this Microsoft download page for the full book as well as additional Razor samples.
There is no easy way to do this in MVC 3 Preview 1. This is a limitation of the preview bits that will be addressed in upcoming releases. Unfortunately _init.cshtml files do not work in this preview of MVC3 so you cannot follow the Web Pages pattern.
There are 2 ways I can think of to make it work (though neither is optimal)
write your own page base class that derives from WebViewPage and sets the right Layout in the constructor... but in that case you would have to specify an #inherits directive in every view.
set the layout override in your action method (using the View(string viewName, string masterName) override). You could write an intermediate controller base class that would have a helper method to save yourself the trouble of repeating the layout everywhere.

MVC Deployment Problem - Site Loads but Links (Routes) do not

Having a problem deploying an MVC application.
Basically the site loads correctly, the home page appears. However anything which needs to access a controller action does not. So all the links just throw up 404 errors.
Does anyone have an Idea why the site loads but after that the controller actions appear not to?
Thanks
Are you running your app in IIS 6? If so you'll need to configure the .mvc extension or configure wildcard mapping. Steve Sanderson has a good post on it.
The fact that the home page appears indicates that you have at least one controller working properly. Namely, the HomeController.
You should check that you are following the default conventions (if you have it set up that way)
Controllers belong in the Controllers folder and follow the naming convention [Name]Controller.
Also, every action in the controller must be public and must return an ActionResult of some kind. Returning a View will cause a particular View to be rendered.
Also, Views follow the folder structure View/[ControllerName]/[Action].aspx
The fact that the first page loads means you probably have Home/Index set up properly for both your Controller and your View. You should take a look at those and see what the difference between that is and the other controllers/actions/views that you've set up.

Resources