Friday, January 11, 2013

Render Partial and Render Action



This sounds slight hard to understand in the begin to differentiate the actual usage.
However, we are sure that the request goes to the controller – action, which in turn returns a action result (Could be View Result, Partial Result, etc…)
Picking up the “RenderAction” method, it is responsible for invoking a controller – action, passing the route value dictionary if required.
Finally the controller, will return a view processing the request and passing the required model object to the view.


In case of “RenderPartial”, it invokes a partial view which may or may not accept a model object.
So in case of “RenderPartial”, it is actually passing an object but representing its view via partial view.

Where as in case of “RenderAction”, might be required to pass route dictionary values but the actual called controller is responsible for invoking the right view passing the model object.
At last, the view is rendered but matters if it done using controller (render action) or using partial view (render partial) passing model object.

Below is a sample code example, demonstrating the use of render partial view and render action.
Sample :
Application is to display list of projects and users.
User details screen shall display user details and also the list of projects and project info to which the user is attached.
Project details screen shall display project info.

Since displaying the project info is common in project and user details screen, project info can be rendered as a user control.
Again Displaying project info control would expect a project name to render, hence there should be a action which accepts project name and returns a project info object to the view.
Beside this, might be I would like to display user name in a different manner like (Mr. User), etc.. for which I would go for partial view which expects the name and it would represent as Mr. [Name].
In this case it is not required to go for action but can invoke the view directly passing the name.

Controller Code :
  public ActionResult Projects()
        {

            if (ProjectsList == null)
                ProjectsList = ProjectUserRepository.GetProjects();
            return View(ProjectsList);
        }

        public ActionResult Users()
        {
            return View(ProjectUserRepository.GetUsers());
        }

        public ActionResult Project(string ProjectName)
        {
            return PartialView(ProjectsList.SingleOrDefault(p => p.ProjectName.Equals(ProjectName)));
        }

        public ActionResult User(string UserName)
        {
            UserModel user = ProjectUserRepository.GetUsers().SingleOrDefault(u => u.UserName.Equals(UserName));
            user.Projects = ProjectsList.Where(p => p.Users.Count(u => u.UserName.Equals(UserName)) > 0).ToList();
            return View(user);
        }


User Info :
@model SampleSite.Models.UserModel

@{
    ViewBag.Title = "User";
}

<h2>User</h2>

<fieldset>
    <legend>UserModel</legend>
    @{
        Html.RenderPartial("_UserInfo", Model);
    }
    <div class="display-label">
        @Html.DisplayNameFor(model => model.UserName)
    </div>
    <div class="display-field">
        @Html.DisplayFor(model => model.UserName)
    </div>

    <div class="display-label">
        @Html.DisplayNameFor(model => model.FirstName)
    </div>
    <div class="display-field">
        @Html.DisplayFor(model => model.FirstName)
    </div>

    <div class="display-label">
        @Html.DisplayNameFor(model => model.LastName)
    </div>
    <div class="display-field">
        @Html.DisplayFor(model => model.LastName)
    </div>
    @foreach (var prj in Model.Projects)
    {
        Html.RenderAction("Project", new { ProjectName = prj.ProjectName });
    }
</fieldset>
<p>
    @Html.ActionLink("Back to List", "Users")
</p>

Project Info :
@model SampleSite.Models.ProjectModel

@{
    ViewBag.Title = "Project";
}

<h2>Project</h2>

<fieldset>
    <legend>ProjectModel</legend>

    <div class="display-label">
         @Html.DisplayNameFor(model => model.ProjectName)
    </div>
    <div class="display-field">
        @Html.DisplayFor(model => model.ProjectName)
    </div>
</fieldset>
<p>
    @Html.ActionLink("Back to List", "Projects")
</p>

User Info Partial View :
@model SampleSite.Models.UserModel
   <div class="display-field">
        Mr. @Html.DisplayFor(model => model.UserName)
    </div>








No comments: