-1

我试图做的是为保存的产品创建一个“超级”实体类。根据产品在应用程序中的位置,某些额外属性是必需的(但并非总是如此)。

例如,当产品在网格中使用时,我希望有一个派生自实体的 ViewModel(继承所有公共字段),然后添加一个唯一标识符属性,如“rowNumber”,以便剑道 ui 轻松搜索网格 CRUD。

我以为我已经完成了所有这些工作,但我遇到了一个障碍……一切都很好并且运行正常,直到我单击批处理网格的“保存”。它执行该函数并且所有数据都存在,但是当它从 CRUD 返回时,它会中断。在萤火虫中,我看到一个异常被抛出,但它永远不会完成(ajax 微调器停留在那里)并且异常中的所有信息都是空的......

我不确定这是否是 c# 不能很好地与 CSLA 配合使用的问题。我不确定。

任何帮助,将不胜感激!我无法上传图像,因为我的代表不够高,否则我会放一张异常的图片,但我至少会放出 Firebug 控制台中出现的内容。其他关于它的一切都是空的......

无限执行且无响应的异常:

GET http://localhost:32574/Exception/SystemException/00000000-0000-0000-0000-000000000000

实体: 这个文件是由 CodeSmith 模板自动生成的,所以它有点荒谬,但它包含出现在视图中的字段值(见下文)。视图上的内容与实体中的内容的例外是实体中未“展平”的字段,因为 Kendo UI 当前不支持可编辑网格内部的这一点。

视图模型:

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; }
}
}

网格控制器:

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"))
    )
)
4

2 回答 2

1

我完全同意。理想情况下,基于 CSLA .NET 的对象是域对象,而不是数据对象,因此符合业务需求所需的形状,而不是数据库表或查询。

可悲的是,很多人最终(误用)像 ORM 一样使用 CSLA,因此拥有以数据为中心的对象,因此失去了框架的很多价值,并且除了需要创建和维护过于复杂的视图模型类型(应该是)业务类型。

于 2013-02-11T06:52:29.123 回答
0

从架构的角度来看,我的团队最终认为将我们的数据库生成的实体与我们的视图如此紧密地联系起来是不明智的。尤其是现在该项目正在多个地方(.Net 应用程序、Webservices 应用程序等)使用。

因此,最终我们为每个实体创建了 ViewModel,以便我们可以灵活地跨多个平台使用我们的实体。这种重组消除了上述问题,因为实体现在从未出现在视图中。

但是请注意:如果您使用的是 Kendo UI,则必须“展平”您希望在单个组件中呈现的视图模型,这些组件是深层对象(例如,另一个对象中的对象)。目前,剑道并不支持这一点。我们正在使用 ValueInjecter。

希望这些信息也能对其他人有所帮助。

于 2012-10-05T14:28:00.093 回答