Search code examples
c#asp.net-mvcasp.net-mvc-4single-responsibility-principle

Render a partial view from another controller


I know a similar question has been asked many times, and the answer is to use an absolute path to the view in question. However, that still uses the current controller, not the controller that the partial view belongs to, to render.

My goal here is to treat a drop-down list for a particular model as a self-contained component, so it can be re-used by other models that have a foreign key to this model. For example, say I have two models: Device, and DeviceType. Device contains a DeviceTypeId field, which in the edit template would be shown as a drop down list, with the names of all available DeviceTypes.

Normally, you would have to wrap the model and the list of device types in a separate DeviceViewModel class, and have the controller populate both before it renders the page. Then you would template it with something like the following:

<div class="editor-field">
    @Html.DropDownListFor(model => model.Device.DeviceTypeId, Model.AllDeviceTypes)
    @Html.ValidationMessageFor(model => model.Device.DeviceTypeId)
</div>

I don't like this solution - for every model, I have to create a matching view model which includes the lookup tables for the drop-down lists. This also means that the DevicesController has to know how to grab the list of DeviceTypes, which seems like a job the DeviceTypesController should be doing. Ideally, I'd like to define a partial view on the DeviceTypesController, which populates and renders a dropdown list, and then all the other views could just include that view:

    <div class="editor-field">
        <!-- Somehow make the DeviceTypesController render the partial here -->
        @Html.ValidationMessageFor(model => model.DeviceTypeId)
    </div>

Is this possible?


Solution

  • You can use RenderAction:

    @{Html.RenderAction("TemplateMethod","DeviceTypes");}
    

    From the following article: http://www.dotnettricks.com/learn/mvc/renderpartial-vs-renderaction-vs-partial-vs-action-in-mvc-razor

    1. This method result will be directly written to the HTTP response stream means it used the same TextWriter object as used in the current webpage/template.
    2. For this method, we need to create a child action for the rendering the partial view.
    3. RenderAction method is useful when the displaying data in the partial view is independent from corresponding view model.For example : In a blog to show category list on each and every page, we would like to use RenderAction method since the list of category is populated by the different model.

      @{Html.RenderAction("Category","Home");}

    4. This method is the best choice when you want to cache a partial view.

    5. This method is faster than Action method since its result is directly written to the HTTP response stream which makes it fast.