-->

26/11/2011

Partial Views with Different Models - MVC Razor


In this post we will see:
1. How to use Different Partial views on a Master View.
2. How to attach models to different Partial Views.


Objective: I wanna create an MVC Razor application which will display both Personnel and Professional Details.


Step 1: Create Models for both Personnel and Professional details.
namespace PartialVsAction.Models
{
    public class ModelA
    {
        public int EmployeeId { get; set; }
        public string EmployeeName { get; set; }        
        public string Comapny { get; set; }
        public int FisacalYear { get; set; }
    }
}
namespace PartialVsAction.Models
{
    public class ModelB
    {
        public int EmployeeId { get; set; }
        public string EmployeeName { get; set; }        
        public string Address { get; set; }
        public string MobileNo { get; set; }
        public string Age { get; set; }
        public int FiscalYear { get; set; }
    }
}
Step 2: Create a regular class file which will act like a DAL, which will supply some data.
namespace PartialVsAction
{
    public class EmployeeService
    {
        public ModelA GetEmployeeProffessionalDetails(int empId, int fiscalYear)
        {
            ModelA objA = new ModelA();
            objA.EmployeeId = empId;
            objA.EmployeeName = "Employee" + empId.ToString();
            objA.Comapny = "Company" + fiscalYear.ToString();
            objA.FisacalYear = fiscalYear;

            return objA;            
        }

        public ModelB GetEmployeePersonnelDeatils(int empId,int fiscaYear)
        {
            ModelB objB = new ModelB();
            objB.EmployeeId = empId;
            objB.EmployeeName = "Employee" + empId.ToString();
            objB.Age = "Age as per " + fiscaYear.ToString();
            objB.Address = "Address" + empId.ToString();
            objB.MobileNo = "Mobile no of " + empId.ToString();
            objB.FiscalYear = fiscaYear;
            return objB;
        }
    }
}
Step 3: Now Define the Partial Views both for Personnel and Professional details.
Personal Partial view (PersonnelPartial.cshtml):
@model PartialVsAction.Models.ModelB

<fieldset>
    <legend>Personnel Details @Model.FiscalYear</legend>
    <table>
    <tr>
    <th>EmployeeId</th>
    <th>EmployeeName</th>
    <th>Address</th>
    <th>Age</th>
    <th>MobileNo</th>
    </tr>
    <tr>
    <td>@Html.DisplayFor(model => model.EmployeeId)</td>
    <td>@Html.DisplayFor(model => model.EmployeeName)</td>
    <td>@Html.DisplayFor(model => model.Address)</td>
    <td>@Html.DisplayFor(model => model.Age)</td>
    <td>@Html.DisplayFor(model => model.MobileNo)</td>
    </tr>
    </table>
   
</fieldset>
Professional Partial View (ProffesionalPartial.cshtml):
@model PartialVsAction.Models.ModelA

<fieldset>

    <legend>Profesional Details @Model.FisacalYear</legend>
    <table>
    <tr>
    <th>EmployeeId</th>
    <th>EmployeeName</th>
    <th>Comapny</th>
    <th>FisacalYear</th>
    </tr>
    <tr>
    <td> @Html.DisplayFor(model => model.EmployeeId)</td>
    <td>@Html.DisplayFor(model => model.EmployeeName)</td>
    <td>@Html.DisplayFor(model => model.Comapny)</td>
    <td>@Html.DisplayFor(model => model.FisacalYear)</td>
    </tr>    
    </table>
    
</fieldset>
Step 4: Create a Master View to host both the personal and Professional partial Views.
Now we have to brainstorm a bit on how we will design the master View.
We have 2 options.
       i. Blank View on which we have to bind Model exclusively for both the partial views.
      ii. Strongly typed View on which we have to bind Model exclusively for only one partial View.
We choose option 2, as its less of a work.
So lets create a Master View with ModelB as model.
Master View (MultiModelView.cshtml) :
@model PartialVsAction.Models.ModelB
@{
    ViewBag.Title = "MultiModelView";
}


<h2>MultiModelView</h2>
<div>
@Html.Partial("PersonnelPartial",Model)
</div>
<div>
@Html.Partial("ProffesionalPartial",Model)
</div>
Now, We have created a disaster. :)
Guess Why?
Answer: Professional partial view is expecting a model to type ModelA. But in Mater View defined above we are supplying ModelB.
So we left with question how to bind the ModelA to a partial view  when Master View is using ModelB?
Answer is simple. As we are using ModelB for Master View, make all other models required for Partial views as a properties of ModelB.

Step 5: Redefine the Models and Master View as per the point discussed above.
ModelA (Professional) :
namespace PartialVsAction.Models
{

    public class ModelA
    {
        public int EmployeeId { get; set; }
        public string EmployeeName { get; set; }        
        public string Comapny { get; set; }
        public int FisacalYear { get; set; }
    }
}
ModelB (Personal) :
namespace PartialVsAction.Models
{
    public class ModelB
    {
        public ModelA ProfessionalDetails;
        public int EmployeeId { get; set; }
        public string EmployeeName { get; set; }        
        public string Address { get; set; }
        public string MobileNo { get; set; }
        public string Age { get; set; }
        public int FiscalYear { get; set; }
    }
}
Master View (MultiModelView.cshtml):
@model PartialVsAction.Models.ModelB
@{
    ViewBag.Title = "MultiModelView";
}


<h2>MultiModelView</h2>
<div>
@Html.Partial("PersonnelPartial",Model)
</div>
<div>
@Html.Partial("ProffesionalPartial",Model.ProfessionalDetails)
</div>

Step 6: Now lets write the action method in HomeController.cs for activating the Master View (MultiModelView.cshtml).
Action Method:
public ActionResult MultiModelView()
        {
            EmployeeService svc = new EmployeeService();
            ModelB personnelinfo = new ModelB();
            personnelinfo = svc.GetEmployeePersonnelDeatils(111,2011);
            personnelinfo.ProfessionalDetails = svc.GetEmployeeProffessionalDetails(111,2011);
            return View(personnelinfo);
        }

Observe carefully how we are attaching the models pertaining to partial Views to master model.
Result:
Objective is Achieved. :)
In next post we will see more about using Partial Views in a different aspect.

Is it helpful for you? Kindly let me know your comments / Questions.

23 comments:

  1. great post keep it up.
    Clear and easy to follow

    ReplyDelete
  2. Great post!...Thanks of your contribution.

    ReplyDelete
  3. Good stuff, starting with asp.net mvc and found myself of this very problem. Great explanation. Thank you.

    ReplyDelete
  4. Very nicely done.

    I do, however, have a question . . . using the view models as you have done, how do you get client-side validation working? If you add the data annotations to the models they will not pass to the client.

    ReplyDelete
    Replies
    1. Data Annotations will work on client side. that is concept of "Remote Validation".
      See :
      http://pratapreddypilaka.blogspot.in/2011/08/mvc-remote-validation.html

      Delete
  5. Pratap, where is the Employee data stored?

    ReplyDelete
    Replies
    1. Hi Johnny
      If you observe GetEmployeePersonnelDeatils() method, its a stub which was used to generate emplyeeid and other details.

      Delete
  6. good example.I found another good example in this link

    http://articlesforprogramming.blogspot.in/2013/07/partial-view-in-aspnet-mvc4.html

    ReplyDelete
  7. Nice example.
    Is it possible to update only professional details of person in single view like in master view in above example.

    ReplyDelete
  8. Nice article, thanks for sharing. But consider a scenario where on a page I nee to bind 2-3 strongly typed partial view and having multiple rows in each set of partial views, also I want to refresh a particular set of partial view in certain condition.

    Is it okay in such situation? I am newbie in MVC4 and do not have more knowledge on it. In ASP.Net 2.0/3.0 it was quite easy to handle. Pls let me know if I am wrong somewhere.

    Thanks,

    ReplyDelete
  9. Thank you for posting this solution. I was really stuck in how to solve this problem.

    You made my day :).

    Ps: Added to my RSS reader from now!

    ReplyDelete
  10. very good article. please keep writing these kind of articles definitely people will appreciate you

    ReplyDelete
  11. I tried using this solution, but my Partial View is being rendered in another partial called _ApplicationLayout.cshtml which is use on every view throughout the project. When I tried to add the Model.ModelA in the _ApplicationLayout.cshtml, it gives an immediate error. In my _ApplicationLayout, @Html.Partial("_CommentsView", Model.ModelA) throws an error. Any assistance you could give would be truly appreciated!

    ReplyDelete
  12. Great Article....it helped me to clarify my concepts about partial views.

    ReplyDelete
  13. Will automapper recognize, that Model.ProfessionalDetails properties are part of nested models ? I have to do it manually but maybe I am doing something wrong.

    ReplyDelete
  14. very good Post easy to understand.

    ReplyDelete
  15. Great post! I am actually getting ready to across this information, It’s very helpful for this blog.Also great with all of the valuable information you have Keep up the good work you are doing well.
    Devops Training in Chennai

    Devops Training in Bangalore

    Devops Training in pune

    ReplyDelete
  16. Great and interesting article to read.. i Gathered more useful and new information from this article.thanks a lot for sharing this article to us..
    Devops Training in Chennai | Devops Training Institute in Chennai

    ReplyDelete