Как создать пакетную сетку пользовательского интерфейса Kendo, в которой используются объектные объекты на платформе CSLA
Я пытаюсь создать класс сущностей Super для сохраненных продуктов. В зависимости от того, где находится продукт в приложении, необходимы определенные дополнительные атрибуты (но не всегда).
Например, когда продукт используется в сетке, я хочу иметь ViewModel, производную от Entity (наследующую все общие поля), а затем добавить атрибут уникального идентификатора, такой как "rowNumber", для удобного поиска в пользовательском интерфейсе kendo. сетка CRUD.
Я думал, что у меня все это работает, но я наткнулся на загвоздку... Все отображается нормально и работает правильно, пока я не нажму "сохранить" для пакетной сетки. Он выполняет функцию и все данные присутствуют, но когда он возвращается из CRUD, он ломается. В firebug я вижу, что генерируется исключение, но оно никогда не завершается (вращатель ajax остается там), и вся информация в исключении пуста...
Я не уверен, если это какая-то проблема с C# не очень хорошо играть с CSLA или нет. Я не уверен
Любая помощь будет оценена! Я не могу загрузить изображения, потому что моя репутация недостаточно высока, иначе я бы поместил изображение исключения, но я, по крайней мере, добавлю то, что появляется в консоли Firebug. Все остальное об этом пусто, хотя...
Исключение с бесконечным выполнением и без ответа:
GET http://localhost:32574/Exception/SystemException/00000000-0000-0000-0000-000000000000
Entity: Этот файл автоматически генерируется шаблоном CodeSmith, поэтому он выглядит бессмысленным, но содержит значения полей, которые отображаются в представлении (см. Ниже). Исключением из того, что находится в представлении, по сравнению с тем, что находится в сущности, являются поля, которые не "сплющены" в сущности, так как пользовательский интерфейс Kendo в настоящее время не поддерживает это внутри редактируемых сеток.
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());
}
}
}
Посмотреть:
@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"))
)
)
2 ответа
С архитектурной точки зрения моя группа, в конечном счете, посчитала неразумным связывать объекты, созданные в нашей базе данных, так близко к нашему представлению. Особенно сейчас, когда проект используется в нескольких местах (приложение.Net, приложение Webservices и т. Д.).
Итак, в итоге мы создали ViewModels для каждой сущности, чтобы мы могли быть гибкими с нашими сущностями на разных платформах. Эта реструктуризация устранила проблему, описанную выше, поскольку объекты теперь никогда не присутствуют в представлении.
Однако, предостережение: если вы используете Kendo UI, вам придется "сгладить" модели представлений, которые вы хотите представить в единственном компоненте, который представляет собой глубокие объекты (например, объект внутри другого объекта). На данный момент Кендо не поддерживает это. Мы используем ValueInjecter.
Надеюсь, эта информация поможет кому-то еще.
Я полностью согласен. В идеале ваши объекты на основе CSLA .NET являются объектами домена, а не объектами данных, и поэтому соответствуют форме, необходимой бизнес-требованиям, а не таблицам базы данных или запросам.
К сожалению, многие люди в конечном итоге (неправильно) используют CSLA, как ORM, и поэтому имеют объекты, ориентированные на данные, поэтому упускают значительную часть инфраструктуры и требуют создания и обслуживания слишком сложных типов моделей представления в дополнение к чему (должны были) виды бизнеса.