Hi,
I am using MVC 4, reposistory pattern and EF 4.3, I am trying to display virtual objects that are in my models.
For example in a products model you may have:
public int ProductID {get;set;}
public string Title {get;set;}
public int CategoryID {get;set;}
public double Price {get;set;}
public bool Discontinued {get;set;}
public virtual Category Category {get;set;}
The the category model may be:
public int CategoryID {get;set;}
public string Name {get;set;}
So in my properties CRUD grid I want the user to see the Products.Category.Name rather than the Products.CategoryID.
I also want a dropdown for users to select the Category name from and this would update the products model with the CategoryID.
The problem I get when I reference Products.Category.Name is that the grid displays "UnDefined" in the category column.
Please can someone show me both the controller actions and the view as an example of how this should be achieved.
I am using Razor views.
Many thanks,
Andy
I am using MVC 4, reposistory pattern and EF 4.3, I am trying to display virtual objects that are in my models.
For example in a products model you may have:
public int ProductID {get;set;}
public string Title {get;set;}
public int CategoryID {get;set;}
public double Price {get;set;}
public bool Discontinued {get;set;}
public virtual Category Category {get;set;}
The the category model may be:
public int CategoryID {get;set;}
public string Name {get;set;}
So in my properties CRUD grid I want the user to see the Products.Category.Name rather than the Products.CategoryID.
I also want a dropdown for users to select the Category name from and this would update the products model with the CategoryID.
The problem I get when I reference Products.Category.Name is that the grid displays "UnDefined" in the category column.
Please can someone show me both the controller actions and the view as an example of how this should be achieved.
I am using Razor views.
Many thanks,
Andy
1 Answer, 1 is accepted
0
andrew
Top achievements
Rank 1
answered on 20 Jul 2012, 01:33 PM
I have managed to create custom helpers and populate them, I have also managed to populate the grid with my data, however I cannot save any CREATE, DESTROY or EDIT actions. I believe this is because I need to translate the dynamic proxy fields back to the entity model.
The entity model I am working with is called "Permissions", within permissions there are "User", "Payroll" and "Function" dynamic proxies.
I found that by passing the "Permissions" repository to the grid with Ajax, my UserName, PayrollTitle and FunctionTitle fields were "Undefined".
I played around for a while and eventually managed to change my ajax query as follows to pass in all the required information.
The commented out code is the originally query to pass data to the view.
The problem was that I could not access "Permisions.User.NetLogin", "Permissions.Payroll.Title" and "Permission.Function.Title".
This got the permissions data in to the view and I made some custom editors which can be seen in my view code below:
This covers the Read() actions and custom editors, however I need some help in how I translate both the controller code and possibly the view code (I'm not sure?) so that the UserID, PayrollID and FunctionID are passed back to the "Permissions" Model.
Please can someone help?
Andy
P.S.
Here is my controller:
The entity model I am working with is called "Permissions", within permissions there are "User", "Payroll" and "Function" dynamic proxies.
I found that by passing the "Permissions" repository to the grid with Ajax, my UserName, PayrollTitle and FunctionTitle fields were "Undefined".
I played around for a while and eventually managed to change my ajax query as follows to pass in all the required information.
[HttpPost] public ActionResult Read() { var perms = unitOfWork.PermissionRepository.Get() .Select(r => new { PermissionID = r.PermissionID, UserID = r.UserID, PayrollID = r.PayrollID, FunctionID = r.FunctionID, Level = r.Level, NetLogin = r.User.NetLogin, PayrollTitle = r.Payroll.Title, FunctionTitle = r.Function.Title }); /* var perms = unitOfWork.PermissionRepository.Get() // Use a view model to avoid serializing internal Entity Framework properties as JSON .Select(p => new Permission { PermissionID = p.PermissionID, UserID = p.UserID, PayrollID = p.PayrollID, FunctionID = p.FunctionID, Level = p.Level }).ToList();*/ return Json(perms); }The commented out code is the originally query to pass data to the view.
The problem was that I could not access "Permisions.User.NetLogin", "Permissions.Payroll.Title" and "Permission.Function.Title".
This got the permissions data in to the view and I made some custom editors which can be seen in my view code below:
@section CustomHeader { @* kendo.common.min.css contains common CSS rules used by all Kendo themes *@ <link href="http://cdn.kendostatic.com/2012.2.710/styles/kendo.common.min.css" rel="stylesheet" /> @* kendo.silver.min.css contains the "Blue Opal" Kendo theme *@ <link href="http://cdn.kendostatic.com/2012.2.710/styles/kendo.silver.min.css" rel="stylesheet" /> <script src="http://cdn.kendostatic.com/2012.2.710/js/kendo.all.min.js"></script>}<h2>Permissions</h2><h3>Page Size: <div id="comboBox"></div></h3><script> $("#comboBox").kendoComboBox({ dataTextField: "text", dataValueField: "value", dataSource: [ { text: 10 }, { text: 25 }, { text: 50 }, { text: 100 }, { text: 500 } ], change: function (e) { var grid = $("#grid").data("kendoGrid"); grid.dataSource.pageSize(this.value()); } });</script>@* The DIV where the Kendo grid will be initialized *@<div id="grid"></div><script>$(document).ready(function () { dataSource = new kendo.data.DataSource({ transport: { create: { url: "@Url.Action("Create", "Permission")", //specify the URL which should create new records. This is the Create method of the HomeController. type: "POST" //use HTTP POST request as the default GET is not allowed for ASMX }, read: { url: "@Url.Action("Read", "Permission")", //specify the URL which should return the records. This is the Read method of the HomeController. type: "POST", //use HTTP POST request as by default GET is not allowed by ASP.NET MVC }, update: { url:"@Url.Action("Update", "Permission")", //specify the URL which should update the records. This is the Update method of the HomeController. type: "POST" //use HTTP POST request as by default GET is not allowed by ASP.NET MVC }, destroy: { url: "@Url.Action("Destroy", "Permission")", //specify the URL which should destroy the records. This is the Destroy method of the HomeController. type: "POST" //use HTTP POST request as by default GET is not allowed by ASP.NET MVC }, parameterMap: function(data, operation) { if (operation != "read") { // post the products so the ASP.NET DefaultModelBinder will understand them: var result = {}; for (var i = 0; i < data.models.length; i++) { var perm = data.models[i]; for (var member in perm) { result["perms[" + i + "]." + member] = perm[member]; } } return result; } }, batch: true, // enable batch editing - changes will be saved when the user clicks the "Save changes" button pageSize: 20, schema: { model: { // define the model of the data source. Required for validation and property types. id: "PermissionID", fields: { PermissionID: { editable: false, nullable: true }, NetLogin: "User", PayrollTitle: "Payroll", FunctionTitle: "Function", Level: { type: "number", validation: { required: true, min: 1} } } } } }}); $("#grid").kendoGrid({ dataSource: dataSource, pageable: true, height: 425, sortable: true, filterable: true, groupable: true, resizable: true, reorderable: true, toolbar: ["create", "save", "cancel"], // specify toolbar commands columns: [ { field: "NetLogin", width: "70px", editor: userDropDownEditor }, { field: "PayrollTitle", width: "70px", editor: payrollDropDownEditor }, { field: "FunctionTitle", width: "70px", editor: functionDropDownEditor }, { field: "Level", width: "70px" }, { command: "destroy", title: "Delete", width: "60px", groupable: false, filterable: false }], editable: true // enable editing });});function userDropDownEditor(container, options) { $('<input data-text-field="NetLogin" data-value-field="NetLogin" data-bind="value:' + options.field + '"/>') .appendTo(container) .kendoDropDownList({ autoBind: false, dataSource: { transport: { read: { url: "@Url.Action("Read", "User")", //specify the URL which should return the records. This is the Read method of the HomeController. type: "POST" //use HTTP POST request as by default GET is not allowed by ASP.NET MVC } } } });}function payrollDropDownEditor(container, options) { $('<input data-text-field="Title" data-value-field="Title" data-bind="value:' + options.field + '"/>') .appendTo(container) .kendoDropDownList({ autoBind: false, dataSource: { transport: { read: { url: "@Url.Action("Read", "Payroll")", //specify the URL which should return the records. This is the Read method of the HomeController. type: "POST" //use HTTP POST request as by default GET is not allowed by ASP.NET MVC } } } });}function functionDropDownEditor(container, options) { $('<input data-text-field="Title" data-value-field="Title" data-bind="value:' + options.field + '"/>') .appendTo(container) .kendoDropDownList({ autoBind: false, dataSource: { transport: { read: { url: "@Url.Action("Read", "Function")", //specify the URL which should return the records. This is the Read method of the HomeController. type: "POST" //use HTTP POST request as by default GET is not allowed by ASP.NET MVC } } } });}</script>This covers the Read() actions and custom editors, however I need some help in how I translate both the controller code and possibly the view code (I'm not sure?) so that the UserID, PayrollID and FunctionID are passed back to the "Permissions" Model.
Please can someone help?
Andy
P.S.
Here is my controller:
using System;using System.Collections.Generic;using System.Data;using System.Data.Entity;using System.Linq;using System.Web;using System.Web.Mvc;using PayPlate.Models;using PayPlate.DAL;using PagedList;namespace PayPlate.Controllers{ public class PermissionController : Controller { UnitOfWork unitOfWork = new UnitOfWork(); public ActionResult Index() { return View(); } /// <summary> /// Creates new products by inserting the data posted by the Kendo Grid in the database. /// </summary> /// <param name="products">The products created by the user.</param> /// <returns>The inserted products so the Kendo Grid is aware of the database generated ProductID</returns> [HttpPost] public ActionResult Create(IEnumerable<Permission> perms) { var result = new List<Permission>(); //Iterate all created products which are posted by the Kendo Grid foreach (var permission in perms) { // Create a new Product entity and set its properties from productViewModel var perm = new Permission { User = permission.User, Payroll = permission.Payroll, Function = permission.Function, Level = permission.Level }; // store the product in the result result.Add(perm); // Add the entity unitOfWork.PermissionRepository.Insert(perm); } // Insert all created products to the database unitOfWork.Save(); // Return the inserted products - the Kendo Grid needs their ProductID which is generated by SQL server during insertion return Json(result.Select(p => new Permission { PermissionID = p.PermissionID, User = p.User, Payroll = p.Payroll, Function = p.Function, Level = p.Level }) .ToList()); } /// <summary> /// Reads the available products to provide data for the Kendo Grid /// </summary> /// <returns>All available products as JSON</returns> [HttpPost] public ActionResult Read() { var perms = unitOfWork.PermissionRepository.Get() .Select(r => new { PermissionID = r.PermissionID, UserID = r.UserID, PayrollID = r.PayrollID, FunctionID = r.FunctionID, Level = r.Level, NetLogin = r.User.NetLogin, PayrollTitle = r.Payroll.Title, FunctionTitle = r.Function.Title }); /* var perms = unitOfWork.PermissionRepository.Get() // Use a view model to avoid serializing internal Entity Framework properties as JSON .Select(p => new Permission { PermissionID = p.PermissionID, UserID = p.UserID, PayrollID = p.PayrollID, FunctionID = p.FunctionID, Level = p.Level }).ToList();*/ return Json(perms); } /// <summary> /// Updates existing products by updating the database with the data posted by the Kendo Grid. /// </summary> /// <param name="products">The products updated by the user</param> [HttpPost] public ActionResult Update(IEnumerable<Permission> perms) { //Iterate all created products which are posted by the Kendo Grid foreach (var permission in perms) { // Attach the entity unitOfWork.PermissionRepository.Update(permission); } // Save all updated products to the database unitOfWork.Save(); //Return emtpy result return Json(null); } /// <summary> /// Destroys existing products by deleting them from the database. /// </summary> /// <param name="products">The products deleted by the user</param> [HttpPost] public ActionResult Destroy(IEnumerable<Permission> perms) { //Iterate all destroyed products which are posted by the Kendo Grid foreach (var permission in perms) { // Delete the entity unitOfWork.PermissionRepository.Delete(permission); } // Delete the products from the database unitOfWork.Save(); //Return emtpy result return Json(null); } }}