开发者

What is a good way to build sub views with logic in ASP.NET MVC 3

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 controlle开发者_运维百科rs.

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.


I think you should go with Action or RenderAction as Darin points out if you want to have logic in your view. However, there is a "hacky" solution that you could use and that is to implement your own IViewPageActivator. Then you could have your views implement a custom WebViewPage and inject services in this WebViewPage and they will be available to your views. To summarize:

  • Use Partial or RenderPartial if you only need to inject the model
  • Use Action or RenderAction if you have some logic in your partial view
  • Implement IViewPageActivator and some other stuff if you really have to

UPDATE: Also, in simple scenarios helpers might do the job for you depending on what you are trying to achieve.


Take a look at client site MVC javascript framework for controlling complex UI. In combination with jquery templating very powerfull and an option to keep an eye on ...

Backbone.js http://documentcloud.github.com/backbone/

Kockout.js http://knockoutjs.com/

Knockout.js vs. Backbone.js – Part 1 http://ifandelse.com/?p=61

Knockout.js vs. Backbone.js – Part 2 http://ifandelse.com/?p=70


Html.Action and Html.RenderAction are the best way to externalize some repeating complex logic in the views that requires its own controllers and models.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜