What I'm attempting to do is have a "Super" entity class for saved products. Depending on where the product is in the application, certain extra attributes are necessary (but not always).
For example, when the product is being used within a grid, I want to have a ViewModel that derives from the Entity (inheriting all of the common fields) and then add a unique identifier attribute like "rowNumber" for easy searching by the kendo ui grid CRUD.
I thought I had all of this working, but I've hit a snag... Everything renders fine and operates correctly until I click "save" for the batch grid. It executes the function and all the data is present, but when it returns from the CRUD, it breaks. In firebug, I see that an exception is being thrown, but it never finishes (the ajax spinner stays there) and all information within the exception is empty...
I'm not sure if this is some issue with c# not playing well with CSLA or not. I'm unsure.
Any help would be appreciated! I can't upload images because my rep isn't high enough or else I would put a picture of the exception, but I'll at least put what appears in the Firebug console. Everything else about it is empty though...
Exception with endless execution and no response:
GET http://localhost:32574/Exception/SystemException/00000000-0000-0000-0000-000000000000
Entity: This file is auto-generated by a CodeSmith template so it is kind of nonsensical, but it holds field values that appear in the view (see below). The exception to what is on the view vs what is in the entity are fields that are not 'flattened' in the entity, as Kendo UI does not currently support this inside of editable grids.
ViewModel:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;
namespace Project.MVC.Models
{
//The MetaData Class is where to put all annotations and validations
[MetadataType(typeof(Project.Business.Shipment.ItemMetaDataClass))]
public class ItemModel : Project.Business.Shipment.Item
{
public ItemModel()
{
}
public long rowNumber { get; set; }
public decimal Length { get; set; }
public decimal Width { get; set; }
public decimal Height { get; set; }
[Display(Name = "UoMDim")]
[UIHint("ItemGrid_RefUnitOfMeasurementListingDimension")]
public string DimensionUnitOfMeasure { get; set; }
[Display(Name = "UoMW")]
[UIHint("ItemGrid_RefUnitOfMeasurementListingWeight")]
public string WeightUnitOfMeasure { get; set; }
[Display(Name = "Weight")]
public decimal WeightValue { get; set; }
[Display(Name = "Type")]
[UIHint("ItemGrid_RefUnitTypeListing")]
public string QuantityUnitOfMeasure { get; set; }
[Display(Name = "Units")]
public decimal QuantityValue { get; set; }
}
}
Grid Controller:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Kendo.Mvc.UI;
using Kendo.Mvc.Extensions;
namespace Project.MVC.Controllers
{
[Authorize]
public class ItemGridController : Csla.Web.Mvc.Controller
{
public ActionResult GetProducts([DataSourceRequest]DataSourceRequest request)
{
Project.MVC.Models.ShipmentModel shipmentModel = (Project.MVC.Models.ShipmentModel)ControllerBase.State.Object;
return Json(shipmentModel.ItemModelList.ToDataSourceResult(request));
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult CreateProducts([DataSourceRequest]DataSourceRequest request, [Bind(Prefix = "models")]IEnumerable<Models.ItemModel> itemsToAdd)
{
Project.MVC.Models.ShipmentModel shipmentModel = (Project.MVC.Models.ShipmentModel)ControllerBase.State.Object;
var results = new List<Models.ItemModel>();
if (ModelState.IsValid)
{
foreach (Models.ItemModel newItem in itemsToAdd)
{
if (shipmentModel.ItemModelList.Count > 0)
{
var nextID = (from i in shipmentModel.ItemModelList
select i.rowNumber).Max() + 1;
newItem.rowNumber = nextID;
}
shipmentModel.ItemModelList.Add(newItem);
results.Add(newItem);
}
}
return Json(results.ToDataSourceResult(request, ModelState));
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult UpdateProducts([DataSourceRequest]DataSourceRequest request, [Bind(Prefix = "models")]IEnumerable<Models.ItemModel> itemsToUpdate)
{
Project.MVC.Models.ShipmentModel shipmentModel = (Project.MVC.Models.ShipmentModel)ControllerBase.State.Object;
var results = new List<Models.ItemModel>();
foreach (var item in itemsToUpdate)
{
Models.ItemModel target = shipmentModel.ItemModelList.Find(i => i.rowNumber == item.rowNumber);
if (target != null)
{
target = item;
}
}
return Json(ModelState.ToDataSourceResult());
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult DeleteProducts([DataSourceRequest]DataSourceRequest request, [Bind(Prefix = "models")]IEnumerable<Models.ItemModel> itemsToDelete)
{
Project.MVC.Models.ShipmentModel shipmentModel = (Project.MVC.Models.ShipmentModel)ControllerBase.State.Object;
foreach (var item in itemsToDelete)
{
shipmentModel.ItemModelList.Remove(item);
}
return Json(ModelState.ToDataSourceResult());
}
}
}
View:
@model Project.MVC.Models.ShipmentModel
@using Kendo.Mvc.UI
@(Html.Kendo().Grid<Project.MVC.Models.ItemModel>()
.Name("QuoteItemGrid")
.Columns(columns =>
{
columns.Bound(i => i.FreightClass)
.EditorTemplateName("ItemGrid_RefFreightClassListing")
.Width(50);
columns.Bound(i => i.Length).Width(30);
columns.Bound(i => i.Width).Width(30);
columns.Bound(i => i.Height).Width(30);
columns.Bound(i => i.DimensionUnitOfMeasure)
.EditorTemplateName("ItemGrid_RefUnitOfMeasurementListingDimension")
.Width(50);
columns.Bound(i => i.QuantityValue).Width(30);
columns.Bound(i => i.QuantityUnitOfMeasure)
.EditorTemplateName("ItemGrid_RefUnitTypeListing")
.Width(50);
columns.Bound(i => i.WeightValue).Width(30);
columns.Bound(i => i.WeightUnitOfMeasure)
.EditorTemplateName("ItemGrid_RefUnitOfMeasurementListingWeight")
.Width(50);
columns.Bound(i => i.NmfcCode).Width(50);
columns.Bound(i => i.ItemDescription).Width(100);
columns.Command(command =>
{
command.Destroy();
}).Width(60);
})
.ToolBar(toolbar =>
{
toolbar.Create();
toolbar.Save();
})
.Editable(editable => editable.Mode(GridEditMode.InCell).CreateAt(GridInsertRowPosition.Bottom))
.Pageable()
.Sortable()
.Scrollable()
.Resizable(resize => resize.Columns(true))
.DataSource(dataSource => dataSource
.Ajax()
.Batch(true)
.ServerOperation(false)
.Events(events => events.Error("QuoteItemGrid_ErrorHandler"))
.Model(model =>
{
model.Id(i => i.rowNumber);
model.Field(i => i.DimensionUnitOfMeasure).DefaultValue("in");
model.Field(i => i.WeightUnitOfMeasure).DefaultValue("lbs");
})
.Create(create => create.Action("CreateProducts", "ItemGrid"))
.Read(read => read.Action("GetProducts", "ItemGrid"))
.Update(update => update.Action("UpdateProducts", "ItemGrid"))
.Destroy(destroy => destroy.Action("DeleteProducts", "ItemGrid"))
)
)