We're building a business application using Microsoft ASP.NET MVC 3. Some views are now becoming so complex that it seems reasonable to divide them into two or more separate views, with separate controllers and models. (Reuse is another reason for wanting to build separate views.)
Which method do you recommend for achieving such separation in ASP.NET MVC?
Partial Views seems like the obvious answer, but as I see it, partial views "out of the box" has little support for separate controllers.
The best solution we've found so far is this, using the Html.RenderAction("<view initialization action method>")
method as explained here: http://www.primaryobjects.com/CMS/Article129.aspx
This post also mentions the RenderAction method: ASP .NET MVC correct UserControl architecture
Do you see any weaknesses with this approach?
Do you recommend any better, easier ways of achieving this?
Take a "Post Detail" view. A composite view that displays both "Post Summary" and "Post Comments".
Taking the partial approach, you'd end up with:
public class PostDetailModel
{
PostSummaryModel Summary { get;set; }
PostCommentsModel Comments { get;set; }
}
and view:
<div id="post_detail">
@Html.Partial("Summary", Model.Summary)
<ul class="comment-list">
@foreach(var comment in Model.Comments)
{
<li>@Html.Partial("Comment", comment)</li>
}
</ul>
</div>
This means that the PostController.Detail method would be responsible for constructing a PostSummaryModel, constructing a PostCommentsModel and selecting which partials to use to render each.
If you then also had the following model:
public class PostListModel
{
ICollection<PostSummaryModel> Posts { get;set; }
}
You would have two actions responsible for constructing a PostSummaryModel and knowing which partial to use. If your application isn't properly structured, this might lead to duplicate data access/model mapping code. But if you delegate and abstract model construction into re-usable model factories (that could be called by both actions) you minimise this risk.
One the other hand, taking the Html.Action approach your model simply becomes:
public class PostDetailModel
{
int PostId { get;set; }
}
and view:
<div id="post_detail">
@Html.Action("Summary", new { Model.PostId })
@Html.Action("Comments", new { Model.PostId })
</div>
It can then be left up the "Summary" and "Comments" actions to construct their own model and select a view.
There is however an ever so slight performance hit in choosing the Html.Action approach because ASP.NET MVC has to go through the whole process of model-binding, executing action filters, validating, etc so you probably wouldn't use Html.Action to display items in a sufficiently long list view. But for creating a composite view it can be a really clean way to stitch together half a dozen or so existing views.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With