7

Having worked with .net in both winforms and ASP.net for a few years I am now starting to get into MVC (a little late I know). One major confusion for me is the concept of reusable 'components', similar to the concept of a usercontrol in webforms.

For example, I would like to have a number of 'widgets' within the members area of my site, one of which is the details of the logged in users account manager. I can create this as a partial however when the page loads the data needs to be passed in as part of the ViewModel / View Data. I would like to use this widget in a number of different sections which would then mean that I need to put the code to pass the data in into a number of different controllers. This seems to violate the DRY principle, or am I missing something here? I would ideally like everything to be encapsulated within the 1 partial which can then be used in any page.

Macros
  • 7,099
  • 2
  • 39
  • 61

1 Answers1

4

You can go three ways:

1) For simple controls without much logic, you can create new instance of the custom view model for the control: Html.RenderPartial("YourControl", new YourControlViewModel () { Param1="value1", Param2 = Model.AnotherValue });

2) If you need some back end logic for the control, you can use Html.RenderAction("ActionName", "SomeControllerName", RouteValuesDictionary); It will call standard controller action, use the view, and insert the resulting output back to the page. You can add [ChildActionOnly] atribute to the controller method to ensure that the method will be available only from the Html.RenderPartial. It is slightly violating the MVC principle (view shouldn't call controller), but its great for widgets, and it is used in the Ruby on Rails world without much issues. You can check great article from Haacked

3) Create custom html helper for tasks like custom date formatting, calculating etc..

In your case, I would choose the number two.

jhexp
  • 685
  • 4
  • 9
  • That makes a lot of sense - I guess in my simple case I could either use no. 1 and retrieve the currently logged in user from the ViewModel constructor, or no.2 if 2 way interaction is required. – Macros Jan 11 '11 at 12:10
  • If the view model has id of the user, you can pass it in the route values, use 2) and cache the data. Another option is to load the current logged in user from the session, it could be very simple, but violates few principles. Mark the answer if you like it, thanks. – jhexp Jan 11 '11 at 12:29