ASP .NET MVC correct UserControl architecture - asp.net-mvc

I'm trying to learn the new ASP .NET MVC framework and would like to know the best practice for using UserControls.
I understand that you can render UserControl's as a partial and pass data to them from a controller. Ideally I would think that it makes sense not to have a code behind file as this creates a temptation to break the MVC rules.
I'll give an example where I don't understand how UserControls fit into the pattern.
I have a UserControl that shows the
latest tags (much like on
StackOverflow). Unlike StackOverflow I
want to display this UserControl on
all of my pages. If I have a
controller say QuestionController
which is meant to handle actions from
some question views e.g. view and
detail, does this mean I have to fetch
the data in the QuestionController and
then pass it to the UserControl?
If I create another controller say
SearchController then I would have to
replicate the same functionality to
get the latest tags to pass to a
partial again. Doesn't this mean that
the 2 different controllers are doing
extra things that they weren't
originally intended to do?

If your UserControl appears on every page, then one way to address this would be to use a base controller from which all of your controllers derive and generate the ViewData for the UserControl by overriding the OnActionExecuting method and putting the logic there. If your UserControl is less pervasive, but still frequently used throughout the site, you could extend ActionFilterAttribute and have your filter generate the needed data. This attribute could be used to decorate the controllers or actions that generate views that use the UserControl.
I'm assuming in all of this that the data for the UserControl is independent of the action being invoked. If there is a dependency, it's probably best to push the logic into a class (or classes, perhaps using Strategy) and make the generation of the data explicit in each action or controller (via overriding OnActionExecuting).

Alternatively, with ASP.NET MVC 2 you can now use RenderAction to call a completely new controller action which can fetch the data. This makes your code much more modular and it is more clear where the data is coming from.

You can also consider putting your model classes in an hierarchy. The upper class (or one of the upper classes) will contain data necessary for your pervasive user controls. Then you can load these commonly used data in a base controller class.

Related

MVC partial views, partial model, partial controller?

Currently i am investigating if MVC is the way to go for the new major version of our web application. We have an existing web application with webparts, dynamically rendered according to some user settings. Each webpart has its own data and own logic (for example, one webpart with user information, one webpart with currently logged-in users, one webpart with appointments etc. etc.).
What we need to accomplish (i think) is to render a single view, which contains several partial views. Each partial view represents a different model, and has its own logic.
I figured out how to put multiple partial views within a single view, but i don't know how to handle the business logic for each view (in "partial controllers"? if possible at al?), and handle the model for each view?
So the main purpose is to render a page with multiple dynamic views (according to what the user has configured), each with its own logic and data. And then when, for example, a button is clicked in a partial view, the corresponding controller is called to handle the event, and returns the updated partial view. The partial views need to be loosely coupled, and updated async.
From what i've seen so far the most tutorials and documentation are focussing on MVC in general, not on how to separete the business logic and model for eachr partial view.
So I'm not asking how to do this, but:
Is it possible to easy accomplish this with MVC 4 or 5?
Does anybody know a good real-life example or tutorial about this?
I hope anyone can point me in the right direction or share some thoughts on this...
You could make one or more controllers with an action for each webpart.
Group all related webparts in the same controller but make an action and View+ViewModel for each webpart. Then use the Html.RenderAction method to call these actions (and have your webparts placed) on your page/main view.
DISCLAIMER: This said, each call to Html.RenderAction creates a complete mvc flow, instanciating a controller, model and view and finally renders the whole thing and passes the value to your page/main view. Having lots of Html.RenderAction has the potential to slow your page creation a lot. You could look into DI/IoC like Unity and consider reusing controllers, or just look into System.Web.Mvc.DependencyResolver to handle the creation of controllers yourself.

Umbraco MVC Implementation - View does not depend on Umbraco implementations

I have followed this nice tutorial which explains how you can take even more advantage of using Umbraco as a content delivery system. Tutorial MVC Umbraco => Your model and views should not depend on specific Umbraco implementations which is a huge advantage for real front-end developers.
The controller inherited from Umbraco.Web.Mvc.RenderMvcController in order to access the data from the CMS.
Now my problem is that we can't use #HTML.actionlink for navigation, it seems that this is only supported in SurfaceController.
Now my question is how would we implement navigation inside Umbraco.Web.Mvc.RenderMvcController? Can we still use the native #HTML.actionlink tag?
No you can't. Simply because all requests pass through a single action. In order to retrieve a path to a CMS-managed page, you need to use the node/content traversal the #Model provides. See here for more details on this.
Edit
To clarify, the author of the article is suggesting that the Umbraco implementation should be more in line with a traditional MVC implementation with little or no logic in the views. Therefore, any querying of node data should happen prior to the view (e.g. in the Mappers). So this is where you would have to retrieve the links.
Umbraco's default MVC implementation forces all requests to go via a single action on a single controller. The author's implementation allows the requests to be shared across one controller per document type - which is better IMO. But it still means that things like Html.ActionLink are redundant in the views since there isn't an action per page.
Further edit
If you wanted to build a navigation list with a combination of Umbraco-managed pages and non-Umbraco pages, regardless of the implementation, I would:
Create a child action and view for the navigation in a separate NavigationController that inherits from the SurfaceController
Use the this.CurrentPage property of the inherited SurfaceController to traverse the Umbraco content cache to retrieve the relevant Umbraco-managed pages. You can then use the Url property of each page result to get its path, and the Name property to get the page title
Use this.Url.Action("action", "controller") to retrieve the paths to specific non-Umbraco actions. Alternatively, if the pages are database-managed, use you data layer (e.g. EF, NHibernate, PetaPoco) at this point
Combine these in a Dictionary to make the list you require where the Key is the path and the Value is the page title
Pass this down to the view as the view model.
Of course there any many more things to consider like caching, but in a nutshell, that's a fairly basic implementation.

ASP.NET MVC - Controller/Actions or Views or ViewModels first?

I'm familiar with the various bits of functionality of the MVC plugin to create things. For example you can create a controller, write an Action method on it, then use the "create view" function in the context menu to create a view for it.
The question is, which is it recommended to do first?
I'm thinking I might start myself a methodology like this:
Plan out what the UI etc will look like and how it will work.
Write unit tests for the controller actions I think I might need.
Create Controller (maybe with default CRUD actions if it's to be that kind of controller).
Create ViewModel class for each controller action.
Create a strongly-typed view for each ViewModel.
Start building the view, working back through the ViewModel to the Controller as the View is built up.
What do you think of this approach, and what do you do?
Sounds like you're on the right track. Controllers are the most easily tested component of the three. Going controller-first will make it easier to follow Test-Driven Development practices.
I've not been perfectly happy with the default view templates, but every MVC guru will point you to T4 templates, which let you roll your own. They, like the out-of-the-box view templates, will be more effective with existing view models and controllers.
I'd be tempted to define the ViewModel first, the VM(s) can consist of all or a subset of the entities required for the various Views. How you segregate your VMs would depend on your app and how you are breaking up logical units within that.
Once I had the VM(s) in a basic form I would move to Model necessary for my chosen data store (unless I had an existing data store in which case I'd have started with the Model). Then onto the controllers. You can then apply TDD with a mocked data source to verify that the VM objects returned by the controller actions match expectations. Lastly, I'd generate basic strongly typed Views (based on the ViewModel objects) for each controller action that actually resulted in UI.
Then it's play time with Jquery and CSS to make it look presentable.

What is the proper structure for Asp.net MVC?

I read the Pro .Net Asp.net MCV book over the weekend and it provides some good examples on setting it up and using it. However my question is what is the structure of an MVC project should be. I ran into problems once I started trying to transfer control from one controller to another. It seems that you can have multiple views within one controller. Also when you execute the Redirect("Action", "Controller") command it seems that the routing wants to look for the view within a sub of that controller. So my questions are:
Is there rule of thumb of 1 controller to 1 view?
Should you call another controller from a controller?
What is the proper way to transfer control from one controller to another?
You can have as many views/partial views per controller. The rule of thumb as far as one can deduce it from the MVC samples is, that a controller encapsulates a set of functionality that belongs together, e.g. listing products and creating, updating, deleting as single product.
You can use Html.ActionLink to route from one view to another. To call one controller from another, IMHO, makes only sense for partial views - however that depends on the problem.
Html.ActionLink or Html.RouteLink.

Controller Passing User Info, or use HttpContext.User?

I recently asked a question about using the Page.User or HttpContext.Current.User in the View. It was recommended I pass the user info through the Controller instead? I've seen this in other posted answer as well.
Why is it recommended to pass the user info through the controller and not use Page.User or HttpContext.User?
This would only be pragmatic if your automating your view testing with Selenium or using some other tool to check your HTML output.
If that is the case using HTTPContext inside your controllers is probably a really bad idea because that will only increase the coupling between your controller actions and HTTPContext.
To gain maximum testability you probably want to setup a controller factory that can inject the User bits into your controller when MVC calls it. That way your action methods remain decoupled from HTTPContext and you gain testability.
If your not using a automated view testing tool it doesn't really matter were you call your HttpContext.User information unless your doing a lot of logic in your view. For example if( HttpContext.User.IsAuthenticated ) or something. If that is the case you can just stick it inside a control and use RenderPartial or bake the logic bits into your viewmodels.
A recommended best practice for MVC is to keep your Views as dumb as possible. Yet, I'd advice against getting all dogmatic about MVC and patterns and what not. Because MVC does not have baked in SubController functionality there are many areas were breaking the MVC pattern is not only encouraged but impossible to not break otherwise. ( see MVC 2 RenderAction, RenderPartial, MasterPages with controls )
Controller should provide all necessary data for view. This makes views more testable. If you use only view model inside view, you can easily write test:
Create view model.
Create view object.
Pass model to view.
Render view.
Check if result is correct.
If you used HttpContext.Current inside of view, you would have to set it up first in your tests, which may not be easy and would add additional dependencies.
It loosens the coupling between your controller and the other classes in the application. By using more of a Dependency Injection pattern, you can increase the testability of the controller. This is because in your tests you would not need to simulate concepts like HttpContext but could simply pass in the user object.

Resources