I'm novice in MVC with c# and I'm wondering why the controller instance constructor will be called frequently (that means more than once).
I have created a typical view based on a layout page. Within the layout page, I'm calling a Kendo TreeView.I'm also using AutoFac and I have added the following instruction to my Global.asax according to AutoFac MVC instruction:
builder.RegisterControllers(typeof(MvcApplication).Assembly);
If I'm debugging, the controller instance constructor which is using the view from above is getting called as soon as the Kendo TreeView is being processed. I can understand if the controller action is called for providing the Kendo TreeView datasource, but I'm not understanding the several calls of this instance constructor. I assumed that there is already an instance of the controller.
Does anyone know if a numerous instance constructor execution of the same controller is normal or is there an error in my coding in general, for instance, I should maybe not place the Kendo Treeview in a layout, maybe in a partial view?
Yours
Stephan
Thanks to Stephen and NightOwl888. I will avoid now creating new instances of other objects within controller's constructor method.
Is it in general a good idea to use AutoFac and register the Controller class as Singleton in order to reuse already created controllers (maybe because I have properties which I won't to reload again) ?
Related
I keep hearing ViewComponents replaced RenderAction in core. However the one big thing I see missing is the ability to handle forms. It would seem ViewComponents can't do this within the view component class where as RenderAction could handle this. I understand the details as to why technically this is the case however, I am using RenderAction in .NET as (what I would refer to as a real self contained component) but the migration to Core sort of scares me because RenderAction was replaced by ViewComponent yet doesn't give the same level of functionality.
I'm just curious on what my options are when I migrate to Core with RenderAction where my "components" are handling form gets/posts. Is there any real conversion for this for Core? The only option I see is to change my component view where it specifies what controller to use and have it be dynamic to get the calling controller name via:
HttpContext.Current.Request.RequestContext.RouteData.Values["controller"]
However, this now means in every place I use this "component" I need to alter the "parent" controller to have this action method and do inside it what my RenderAction component was which seems like a horrible idea.
I have a small confusion in Asp.Net MVC
How rendering works in Asp.net MVC? We invoke View function - > Which will find the view and ask ViewEngine to parse it. Because of ViewEngine final outcome is HTML.
1)Whatever ViewData we create its available inside View. My understanding is ViewData and View function both are part of controller base class which makes ViewData available inside View function. Is it correct?
2)Finally Whats the point with WebViewPage class. ViewData keyword we use inside View(.cshtml) page is coming from the WebViewPage class. What role WebViewPage plays here.
I will really appreciate If you can point me with some good resource to understand the same
1) ViewData is merely a dictionary of objects that you can fill in the Controller and retrieve within the view. Since it is a dictionary of objects you need to cast the data back into the type it was to make full use of it.
2) WebViewPage is the base type of a razor page. It is the defined class which razor pages are compiled into at runtime. The web.config inside the views folder specifies the pageBaseType of the razor pages specifically to WebViewPage. These are two good resources regarding why its use and how you can extend it. Link1 and Link2.
Go peek inside he source code that renders the views
visit msdn
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.
Q: How do I make an object that is instantiated inside an action-filter available within the action-method?
Background:
I have numerous forms (among other things) in an MVC web site.
Each has its own viewmodel, which inherits from a base type (FormPage).
My convention for these is to name the viewmodel type as the action-name prepended with "Form". So my ContactUs viewmodel is FormContactUs : FormPage.
A number of base viewmodel properties are set identically for all forms, and I have a generic utility functon that I call inside the action method to do this.
Setting the viewmodel, choosing the type based on the action-name and the naming convention, and setting base properties common to all forms from within an action-filter will make this just a bit DRY-er. My only hurdle appears to be figuring out how to make an object instantiated inside the filter available within the action-method.
Q: How do I make an object that is instantiated inside an action-filter available within the action-method?
You could store it in the HttpContext.Items which is available throughout the entire request lifecycle. This being said, a custom model binder seems more adapted to your scenario than an action filter.
I am porting an asp.net webforms application to mvc.net. I have an OR framework that requires a DataSession object to be created before any database operations can be performed.
In my current webform application I instantiate the DataSession during the Page_Init event and during the Page_UnLoad event I clear the object.
I am looking for something similar with mvc.net. I have initially started with using the OnACtionExecuting (raised before an action) and OnActionExecuted (raised after the action). However, during the rendering of the page there is some lazy loading of entities that fail as the DataSession is no longer available. What I need is something that will fire after the View has been rendered.
You shouldn't let lazy loading occur in your view pages. That means the view accesses data which breaks the entire point of MVC.
Instead you should get the entirety of the data in your controller and then pass that to your view.
Load the db connection in OnActionExecuting and unload in OnResultExecuted.
Although I would use Application_BeginRequest and Application_EndRequest in global.asax.
I haven't used these methods before, but perhaps look into overriding OnResultExecuted or OnResultExecuting.