In this article, I will demonstrate how to work with ViewModel in ASP.NET MVC5 Using jQuery Ajax and Strongly Typed View. After going through this article, you will get the benefits of ViewModel features. Okay! Let's move forward.
ViewModels allow you to shape multiple entities from one or more data models or sources into a single object, optimized for consumption and rendered by the view. With the help of ViewModels, we can work with multiple models in a time.
To create a View Model we must have more than a model or entity in our project. So, now let's create the model first. In the below, you can see that I have created two models with the name of Employee and Contact.
These are the normal model or entity. Now let's create a ViewModel. In the below code you can see that I have created aEmployeeContact_ViewModel. While creating a ViewModel, we have to mention which model or entity should exist in ViewModel.
- public class EmployeeContact_ViewModel
- {
- public Employee employeeDetails { get; set; }
- public Contact contactDetails { get; set; }
- }
Add the dummy values to ViewModel
Before Adding dummy values to it, let's create the controller and action.
Create a Controller and View
Now, create an empty Controller and View. Here, I created a Controller with the name of "DemoController". Whenever we create an empty Controller, it is created with an empty Index action method. And I have created a LoadEmployees Action.
- Employee emp = new Employee();
- emp.EmpID = 1;
- emp.Name = "Gnanavel Sekar";
- emp.Designation = "Sr.Software Engineer";
- Contact contact = new Contact();
- contact.EmpID = 1;
- contact.Address = "test";
- contact.Email = "[email protected]";
- contact.MobileNo = "9876543210";
- EmployeeContact_ViewModel viewModel = new EmployeeContact_ViewModel()
- {
- contactDetails = contact,
- employeeDetails = emp
- };
Create the Strongly Typed View
To know about Strongly Typed View refer
here. Likewise, I have created a strongly typed view below.
- @model ViewModelUsingJqueryAjax.Models.EmployeeContact_ViewModel
- @ {
- ViewBag.Title = "LoadEmployees";
- }
- @using(Html.BeginForm()) {
- @Html.AntiForgeryToken() < div class = "form-horizontal" > < h4 > Employee < /h4> < hr / > @Html.ValidationSummary(true, "", new {
- @class = "text-danger"
- }) < div class = "form-group" > @Html.LabelFor(model => model.employeeDetails.EmpID, htmlAttributes: new {
- @class = "control-label col-md-2"
- }) < div class = "col-md-10" > @Html.EditorFor(model => model.employeeDetails.EmpID, new {
- htmlAttributes = new {
- @class = "form-control"
- }
- })
- @Html.ValidationMessageFor(model => model.employeeDetails.EmpID, "", new {
- @class = "text-danger"
- }) < /div> < /div> < div class = "form-group" > @Html.LabelFor(model => model.employeeDetails.Name, htmlAttributes: new {
- @class = "control-label col-md-2"
- }) < div class = "col-md-10" > @Html.EditorFor(model => model.employeeDetails.Name, new {
- htmlAttributes = new {
- @class = "form-control"
- }
- })
- @Html.ValidationMessageFor(model => model.employeeDetails.Name, "", new {
- @class = "text-danger"
- }) < /div> < /div> < div class = "form-group" > @Html.LabelFor(model => model.employeeDetails.Designation, htmlAttributes: new {
- @class = "control-label col-md-2"
- }) < div class = "col-md-10" > @Html.EditorFor(model => model.employeeDetails.Designation, new {
- htmlAttributes = new {
- @class = "form-control"
- }
- })
- @Html.ValidationMessageFor(model => model.employeeDetails.Designation, "", new {
- @class = "text-danger"
- }) < /div> < /div> < h4 > Contact < /h4> < hr / > @Html.ValidationSummary(true, "", new {
- @class = "text-danger"
- }) < div class = "form-group" > @Html.LabelFor(model => model.contactDetails.MobileNo, htmlAttributes: new {
- @class = "control-label col-md-2"
- }) < div class = "col-md-10" > @Html.EditorFor(model => model.contactDetails.MobileNo, new {
- htmlAttributes = new {
- @class = "form-control"
- }
- })
- @Html.ValidationMessageFor(model => model.contactDetails.MobileNo, "", new {
- @class = "text-danger"
- }) < /div> < /div> < div class = "form-group" > @Html.LabelFor(model => model.contactDetails.Address, htmlAttributes: new {
- @class = "control-label col-md-2"
- }) < div class = "col-md-10" > @Html.EditorFor(model => model.contactDetails.Address, new {
- htmlAttributes = new {
- @class = "form-control"
- }
- })
- @Html.ValidationMessageFor(model => model.contactDetails.Address, "", new {
- @class = "text-danger"
- }) < /div> < /div> < div class = "form-group" > @Html.LabelFor(model => model.contactDetails.Email, htmlAttributes: new {
- @class = "control-label col-md-2"
- }) < div class = "col-md-10" > @Html.EditorFor(model => model.contactDetails.Email, new {
- htmlAttributes = new {
- @class = "form-control"
- }
- })
- @Html.ValidationMessageFor(model => model.contactDetails.Email, "", new {
- @class = "text-danger"
- }) < /div> < /div> < div class = "form-group" > < div class = "col-md-offset-2 col-md-10" > < input type = "submit"
- id = "btnViewModel"
- value = "Create"
- class = "btn btn-default" / > < /div> < /div> < /div>
- } < div > @Html.ActionLink("Back to List", "Index") < /div>
You can see that I have created the button with a type of submitting. So, here we can directly pass our view data to the controller using a strongly typed view.
- <input type="submit" id="btnViewModel" value="Create" class="btn btn-default" />
And create a post action in a controller.
- [HttpPost]
- public ActionResult LoadEmployees(EmployeeContact_ViewModel viewModel)
- {
- return View();
- }
Now, run your application.
We returned the static data to View Model and the ViewModel is bound to each control by using a strongly typed view. Here we can get the view data in the controller using a strongly typed view. In some cases, we will go with the Client side. In that case, we have to know how to pass the ViewModel from jQuery to Ajax right?. Now let's see that
Pass ViewModel From jQuery Ajax
First, we will change the button type because we need to call our jQuery function right? Otherwise, it automatically calls the post action while we have the strongly typed view. So, I have changed the type="submit" to type="button" as below.
- <input type="button" id="btnViewModel" value="Create" class="btn btn-default" />
Now let's write the logic to fetch the value from our view controller. We can get nested class properties id in jQuery, using “@Html.IdFor()”. In the following way, we can read nested class properties value. Or we can define the id for our control and get the value by directly mentioning the control id.
- $('#@Html.IdFor(m=>m.employeeDetails.EmpID)').val();
In the below code, we have created two objects with the name of employeeDetails, contactDetails and we assigned the value to it. Each and every model object should match here otherwise we will not get the data in our controller.
- <script type="text/javascript">
- $(document).ready(function() {
- $("#btnViewModel").click(function() {
- var employeeDetails = {
- EmpID: $('#@Html.IdFor(m=>m.employeeDetails.EmpID)').val(),
- Name: $('#@Html.IdFor(m=>m.employeeDetails.Name)').val(),
- Designation: $('#@Html.IdFor(m=>m.employeeDetails.Designation)').val()
- }
- var contactDetails = {
- MobileNo: $('#@Html.IdFor(m=>m.contactDetails.MobileNo)').val(),
- Address: $('#@Html.IdFor(m=>m.contactDetails.Address)').val(),
- Email: $('#@Html.IdFor(m=>m.contactDetails.Email)').val(),
- EmpID: $('#@Html.IdFor(m=>m.employeeDetails.EmpID)').val(),
- }
- var viewModel = {
- "employeeDetails": employeeDetails,
- "contactDetails": contactDetails
- }
- $.ajax({
- type: "post",
- url: "/Demo/LoadEmployees",
- data: viewModel,
- datatype: "json",
- cache: false,
- success: function(data) {
- alert("View Model Passed Successfully");
- },
- error: function(xhr) {
- alert('No Valid Data');
- }
- });
- });
- });
- </script>
Now, run your application, After clicking create a button,
Complete Controller
- using System.Web.Mvc;
- using ViewModelUsingjQueryAjax.Models;
- namespace ViewModelUsingjQueryAjax.Controllers {
- public class DemoController: Controller {
-
- public ActionResult Index() {
- return View();
- }
- public ActionResult LoadEmployees() {
- Employee emp = new Employee();
- emp.EmpID = 1;
- emp.Name = "Gnanavel Sekar";
- emp.Designation = "Sr.Software Engineer";
- Contact contact = new Contact();
- contact.EmpID = 1;
- contact.Address = "test";
- contact.Email = "[email protected]";
- contact.MobileNo = "9876543210";
- EmployeeContact_ViewModel viewModel = new EmployeeContact_ViewModel() {
- contactDetails = contact,
- employeeDetails = emp
- };
- return View(viewModel);
- }
- [HttpPost]
- public ActionResult LoadEmployees(EmployeeContact_ViewModel viewModel) {
- return View();
- }
- }
- }
View (LoadEmployee.cshtml)
- @model ViewModelUsingjQueryAjax.Models.EmployeeContact_ViewModel
- @ {
- ViewBag.Title = "LoadEmployees";
- } < script src = "http://code.jQuery.com/jquery-1.11.3.min.js" > < /script> < script type = "text/javascript" > $(document).ready(function() {
- $("#btnViewModel").click(function() {
- var employeeDetails = {
- EmpID: $('#@Html.IdFor(m=>m.employeeDetails.EmpID)').val(),
- Name: $('#@Html.IdFor(m=>m.employeeDetails.Name)').val(),
- Designation: $('#@Html.IdFor(m=>m.employeeDetails.Designation)').val()
- }
- var contactDetails = {
- MobileNo: $('#@Html.IdFor(m=>m.contactDetails.MobileNo)').val(),
- Address: $('#@Html.IdFor(m=>m.contactDetails.Address)').val(),
- Email: $('#@Html.IdFor(m=>m.contactDetails.Email)').val(),
- EmpID: $('#@Html.IdFor(m=>m.employeeDetails.EmpID)').val(),
- }
- var viewModel = {
- "employeeDetails": employeeDetails,
- "contactDetails": contactDetails
- }
- $.ajax({
- type: "post",
- url: "/Demo/LoadEmployees",
- data: viewModel,
- datatype: "json",
- cache: false,
- success: function(data) {
- alert("View Model Passed Successfully");
- },
- error: function(xhr) {
- alert('No Valid Data');
- }
- });
- });
- }); < /script>
- @using(Html.BeginForm()) {
- @Html.AntiForgeryToken() < div class = "form-horizontal" > < h4 > Employee < /h4> < hr / > @Html.ValidationSummary(true, "", new {
- @class = "text-danger"
- }) < div class = "form-group" > @Html.LabelFor(model => model.employeeDetails.EmpID, htmlAttributes: new {
- @class = "control-label col-md-2"
- }) < div class = "col-md-10" > @Html.EditorFor(model => model.employeeDetails.EmpID, new {
- htmlAttributes = new {
- @class = "form-control"
- }
- })
- @Html.ValidationMessageFor(model => model.employeeDetails.EmpID, "", new {
- @class = "text-danger"
- }) < /div> < /div> < div class = "form-group" > @Html.LabelFor(model => model.employeeDetails.Name, htmlAttributes: new {
- @class = "control-label col-md-2"
- }) < div class = "col-md-10" > @Html.EditorFor(model => model.employeeDetails.Name, new {
- htmlAttributes = new {
- @class = "form-control"
- }
- })
- @Html.ValidationMessageFor(model => model.employeeDetails.Name, "", new {
- @class = "text-danger"
- }) < /div> < /div> < div class = "form-group" > @Html.LabelFor(model => model.employeeDetails.Designation, htmlAttributes: new {
- @class = "control-label col-md-2"
- }) < div class = "col-md-10" > @Html.EditorFor(model => model.employeeDetails.Designation, new {
- htmlAttributes = new {
- @class = "form-control"
- }
- })
- @Html.ValidationMessageFor(model => model.employeeDetails.Designation, "", new {
- @class = "text-danger"
- }) < /div> < /div> < h4 > Contact < /h4> < hr / > @Html.ValidationSummary(true, "", new {
- @class = "text-danger"
- }) < div class = "form-group" > @Html.LabelFor(model => model.contactDetails.MobileNo, htmlAttributes: new {
- @class = "control-label col-md-2"
- }) < div class = "col-md-10" > @Html.EditorFor(model => model.contactDetails.MobileNo, new {
- htmlAttributes = new {
- @class = "form-control"
- }
- })
- @Html.ValidationMessageFor(model => model.contactDetails.MobileNo, "", new {
- @class = "text-danger"
- }) < /div> < /div> < div class = "form-group" > @Html.LabelFor(model => model.contactDetails.Address, htmlAttributes: new {
- @class = "control-label col-md-2"
- }) < div class = "col-md-10" > @Html.EditorFor(model => model.contactDetails.Address, new {
- htmlAttributes = new {
- @class = "form-control"
- }
- })
- @Html.ValidationMessageFor(model => model.contactDetails.Address, "", new {
- @class = "text-danger"
- }) < /div> < /div> < div class = "form-group" > @Html.LabelFor(model => model.contactDetails.Email, htmlAttributes: new {
- @class = "control-label col-md-2"
- }) < div class = "col-md-10" > @Html.EditorFor(model => model.contactDetails.Email, new {
- htmlAttributes = new {
- @class = "form-control"
- }
- })
- @Html.ValidationMessageFor(model => model.contactDetails.Email, "", new {
- @class = "text-danger"
- }) < /div> < /div> < div class = "form-group" > < div class = "col-md-offset-2 col-md-10" > < input type = "button"
- id = "btnViewModel"
- value = "Create"
- class = "btn btn-default" / > < /div> < /div> < /div>
- } < div > @Html.ActionLink("Back to List", "Index") < /div>
Refer to the attached project for reference and I did attach the demonstrated project without package due to the size limit.
In this article, we discussed how to work with ViewModel in ASP.NET MVC5 Using jQuery Ajax and Strongly Typed View.
I hope it will help you out. Your valuable feedback and comments about this article are always welcome.