I was wondering if theres a way of using controllers for my master pages.
Cheers
Not really. But you can create a Controller for a document type. Which is probably what you want to do.
If you inherit a controller from Umbraco.Web.Mvc.RenderMvcController and name it appropriately, this controller will be picked up automatically by Umbraco.
In the index method you can control the Model which is passed to the view.
The naming of the controller has to be DocTypeAliasController.
It's described in the documentation as "Custom controllers":
http://our.umbraco.org/Documentation/Reference/Templating/Mvc/custom-controllers
If you are using forms and posting back information, you should look at the SurfaceControllers:
http://our.umbraco.org/documentation/reference/templating/mvc/surface-controllers
Related
I've been reading a lots of blogs on MVC provided here:
http://www.sitecore.net/Community/Technical-Blogs/John-West-Sitecore-Blog.aspx
However, I am not being able to explain/convience myself/team:
When to use custom control vs. out of box site core controller?
When does the Out of Box Controller gets invoked?
Benifit of custom control vs. out of box controllers?
If we go with out of box, should we include all business logic on Views. Is this testable?
I also looked at below and still not certain:
https://bitbucket.org/demoniusrex/launch-sitecore-mvc-demo
Any help will be appreciated.
Whilst I broadly agree with Kevin Obee's statement I think it's worth reminding ourselves that controllers are being used in two distinct roles in Sitecore:
Page level controller (invoked by item route)
Component level controller (invoked by redering mechanism)
When to use: Custom controller / default Sitecore controller
Page level controller
Any route that matches an item path will by default use the Index action on the Sitecore.Mvc.Controllers.SitecoreController. This action will return a ViewResult based on the layout configuration of the item.
If you have a need for changing this behaviour (e.g. something that impacts the entire page) you can specify a custom controller and action on the item (or the Standard Values for the item). For the custom controller you can either roll your own or subclass the default controller.
Component level controller
For ViewRendering Sitecore renders the Razor views without the need for a specific controller (well I guess it's the page level controller that is in play - but just imagine that Sitecore provides a default controller that gets the model using the mvc.getModel pipeline and feeds it to the Razor view).
For ControllerRendering you provide a custom controller that can execute logic (see Kevin's answer) and provide a model for the view. There is no benefit from subclassing Sitecore.Mvc.Controllers.SitecoreController.
When are controllers invoked
Page level controller
The action on the page level controller is invoked by the routing engine.
Component level controller
The action on a ControllerRendering is invoked as the page view renders.
Benefit of using: Custom controller / default Sitecore controller
The benefit of a custom controller over the default Sitecore controller is that you are in control of the logic. The benefit of using the default Sitecore controller is that Sitecore provides the logic for you.
Should we include all business logic on Views
No. (See Kevin's answer)
My personal view is that the business logic should go in command and query classes that are invoked from the controller class. From these calls you can assemble a strongly typed view model which gets passed to a dumb razor view for rendering.
Ensure that any services that the controller relies on are passed into it via constructor injection using contracts (interfaces) instead of concrete classes and you should end up with solution that is unit testable.
In ASP.NET MVC I am looking to process, and display, all (or most) of the controller metadata when loading up a single page.
Say: /home/index would display all the controllers and their metadata.
Is there a good way to access the ControllerDescriptor for each controller? Maybe load them up calling into the controller factory? I really don't want to fall back to reflection for this type of work.
So there are two extensions that do what you want (both on nuget)
There is phil haack's Controller Inspector :
http://www.codertakeout.com/v/4T4NO/Writing_an_ASPNET_MVC_Controller_Inspector.html
Nuget : https://preview.nuget.org/packages/MvcHaack.ControllerInspector
Github : https://github.com/Haacked/CodeHaacks
Then there is also Glimpse:
http://www.hanselman.com/blog/NuGetPackageOfTheWeek5DebuggingASPNETMVCApplicationsWithGlimpse.aspx
How do I associate a PartialView which will be used across the app with a Child Action? For example the PartialView could be a login bar at the top of the page which will need to have some associated logic (loading the model etc) which I would normally put in a ChildAction.
However, I don't know what Controller will be used. I think I could create a base Controller class with the ChildAction and then inherit from that but I was hoping there would be a more elegant solution.
The RenderAction method allows for selecting the controller:
http://msdn.microsoft.com/en-us/library/ee839451.aspx
I would like to code some logic into my views that depends on the name of the controller action used to call the view. Is there a way I can find out this name.
Hope somebody can help me with that. Please note that it's MVC3 I am using.
Get the name of the controller
#ViewContext.Controller.ValueProvider.GetValue("controller").RawValue
Get the name of the action
#ViewContext.Controller.ValueProvider.GetValue("action").RawValue
I found that here.
#ViewContext.RouteData.Values["Controller"]
#ViewContext.RouteData.Values["Action"]
While this works, I'd suggest it's a little inelegant. Personally I'd add these options as flags to a ViewModel and pass that to my View.
ViewContext.RouteData.Values["action"] may be used, but it is bad choise to let view decide such things. You could use display and editor templates to generate different views and then let action choose its view. Views should be very simple and rely on data that that receive via ViewData or their model. Best to let controller decide such things as differenciate some views with action
So if there is some global state that every view of an MVC app will need to render ... for example: IsUserLoggedOn and UserName ... whats the appropriate way of getting that information to every view?
I understand that that part of the view should be in the master page or in a partial view thats added to the other views. But whats a good way to make sure the 'global' model data is passed to the view every time from all the relevant controllers and actions?
After asking this, I found this good blog post by Steve Sanderson:
http://blog.stevensanderson.com/2008/10/14/partial-requests-in-aspnet-mvc/
He suggests three different approaches:
Use a base controller class or ActionFilter to add the relevant model to the ViewData[] collection every time. I think a few people have suggested that sort of thing already.
Use Html.RenderAction() in the view ... and as he says:
If someone tells you that internal
subrequests are bad because
it “isn’t MVC”, then just bite them on
the face immediately. Also ask them
why they’re still willing to use Ajax,
and even <IMG> tags for that matter,
given that both are a form of
subrequest.
Use 'Partial Requests' (he provides the code for this on his blog) which allow one controller to nest calls to other controllers into a sortof nested ViewData structure.
codeulike - see the answer to a similar question asked at exactly the same time as this:
ASP.NET MVC displaying user name from a Profile
in a nutshell, basically create a base controller that's inherited by all your other controllers. the base controller then has an override function that carries thro' to all 'child' controllers. rather than duplicate the code, take a look at my answer above and give it a try..
cheers...
You could create base class for viewmodel which contains shared information and inherit that for each viewmodel.
public class ViewModelBase
{
// shared data
}
public class Page1ViewModel : ViewModelBase
{
// page 1 data
}
In masterpage you could use that base class
Inherits="System.Web.Mvc.ViewMasterPage<ViewModelBase>"
and in each view use those derived classes
Inherits="System.Web.Mvc.ViewPage<Page1ViewModel>"