1

更新:我还没有弄清楚任何事情。看起来它确实应该按原样工作。

我有一个绑定到视图模型的 Telerik 网格。网格基本上显示车辆对象的名称和类型。在 Datakeys 中,我添加了 VehicleID 和 Timestamp 字段。当网格发布 ajax 更新时,Timestamp 字段为空。

我已经验证了视图模型中的时间戳字段在传递给视图时有一个值。

以下是相关代码:

看法:

...
@(Html.Telerik().Grid(Model)
.Name("Grid")
.Columns(columns =>
{
    columns.Bound(o => o.VehicleID).Visible(false);        
    columns.Bound(o => o.VehicleName);
    columns.Bound(o => o.VehicleType);
})
.DataBinding(dataBinding =>
    {
        dataBinding.Server().Select("Index", "Vehicle");
        dataBinding.Ajax().Select("_Index", "Vehicle").Enabled(true);
        dataBinding.Ajax().Update("_SaveVehicle", "Vehicle");
        dataBinding.Ajax().Delete("_DeleteVehicle", "Vehicle");
    })
    .Scrollable(scrolling => scrolling.Enabled(true))
    .Sortable(sorting => sorting.Enabled(true))
    .Pageable(paging => 
        paging.Enabled(true)
        .PageSize(20)
        .Position(GridPagerPosition.Bottom))
    .Filterable(filtering => filtering.Enabled(true))
    .Groupable(grouping => grouping.Enabled(true))
    .Footer(true)
    .ToolBar(toolbar => toolbar.Template(
        @<text>
            @using (Html.BeginForm("ExportCsv", "Vehicle", FormMethod.Post, new {id = "export"}))
            {
                <text>
                    <input type="submit" value="Export to CSV" id="export" />
                </text>
            }

            <label class="error">@ViewBag.AjaxErrorMessage</label>

        </text>
        ))            

    .Columns(columns =>
        {
            columns.Command(command =>
                {
                    command.Custom("details").Text("Details").Action("Edit", "Vehicle").HtmlAttributes(new { style = "text-align: center" }) ;
                    command.Edit().ButtonType(GridButtonType.Image);
                    command.Delete().ButtonType(GridButtonType.Image);
                }).Width(165);
        })
    .DataKeys(dataKeys => 
        {
            dataKeys.Add(key => key.Timestamp).RouteKey("Timestamp");
            dataKeys.Add(key => key.VehicleID).RouteKey("VehicleID"); 

        })
    .ClientEvents(events => events.OnEdit("onEdit"))
    .ColumnContextMenu()
    .Resizable(config =>
        {
            config.Columns(true);
        })
    .Reorderable(config =>
        {
            config.Columns(true);
        })

)

<script type = "text/javascript">
function onEdit(e) {
    $(e.form).find('#VehicleType').data('tDropDownList').select(function (dataItem) {
        return dataItem.Text == e.dataItem['vehicleType'];
    });
}
</script>

查看型号:

using System;
using System.ComponentModel.DataAnnotations;

namespace ShopLog.ViewModels
{
    public class VehicleIndexViewModel
    {

    //public IEnumerable<Vehicle> Vehicles { get; set; }
    [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid VehicleID { get; set; }

    [Timestamp]
    public Byte[] Timestamp { get; set; }

    [Required]
    [Display(Name = "Vehicle Name")]
    [MaxLength(30, ErrorMessage = "The {0} must be no more than {2} characters long.")]
    public string VehicleName { get; set; }

    [Display(Name = "Fuel Type")]
    [StringLength(30, ErrorMessage = "\"{0}\" must be no more than {1} characters long.")]
    public string FuelType { get; set; }

    [Display(Name = "Notes")]
    [DataType(DataType.MultilineText)]
    public string Notes { get; set; }

    [UIHint("VehicleType")]
    [Display(Name = "Type")]
    public string VehicleType { get; set; }

    [Display(Name = "Transmission Type")]
    public String TransmissionType { get; set; }
    }
}

Controller Post Code for Update 在第一行放置一个断点表明vehicleIndexViewModel 的timestamp 属性为空。我试图从表单集合中获取时间戳,但它在那里也是空的。

[AcceptVerbs(HttpVerbs.Post)]
    [GridAction]
    public ActionResult _SaveVehicle(VehicleIndexViewModel vehicleIndexViewModel, FormCollection formcollection)
    {          

        if (TryUpdateModel(vehicle))
        {
            try
            {
                //Delete the record
                db.Entry(vehicle).State = EntityState.Modified;
                db.SaveChanges();
            }
            catch (DbUpdateConcurrencyException)
            {
                ViewBag.AjaxErrorMessage = "That record has been edited by someone else since you started editing it.";
            }
            catch (DataException)
            {
                ViewBag.AjaxErrorMessage = "Error saving data, please try again.";
            }
        }
        //Rebind the grid
        PopulateVehicleTypes();
        return View(new GridModel(GetIndexViewData()));
    }

谢谢!

4

1 回答 1

1

这是我发现的:

byte[] 不能很好地从 ViewModel 传回。为什么?我不知道。

我最终将 ViewModel 中的“时间戳”字段设为字符串而不是字节 []。当我将数据从模型传递到视图模型时,我调用“Convert.ToBase64String( value )”。当我将数据从 ViewModel 传递回 Model 时,调用“Convert.FromBase64String( value )”。

模型:

[Timestamp]
public Byte[] Timestamp { get; set; }

视图模型:

[Timestamp]
public string Timestamp {get; set;}

控制器:

    [AcceptVerbs(HttpVerbs.Post)]
    [GridAction]
    public ActionResult _SaveVehicle(VehicleIndexViewModel vehicleIndexViewModel)
    {
        Vehicle vehicle = Mapper.Map<VehicleIndexViewModel, Vehicle>(vehicleIndexViewModel);

        if (TryUpdateModel(vehicle))
        {
            try
            {
                //Delete the record
                db.Entry(vehicle).State = EntityState.Modified;
                db.SaveChanges();
            }
            catch (DbUpdateConcurrencyException)
            {
                ViewBag.AjaxErrorMessage = "That record has been edited by someone else since you started editing it.";
            }
            catch (DataException)
            {
                ViewBag.AjaxErrorMessage = "Error saving data, please try again.";
            }
        }
        //Rebind the grid
        PopulateVehicleTypes();
        return View(new GridModel(GetIndexViewData()));
    }

Global.ascx 中的自动映射器映射

AutoMapper.Mapper.CreateMap<ShopLog.Models.Vehicle, ShopLog.ViewModels.VehicleIndexViewModel>().ForMember(m => m.Timestamp, opt => opt.ResolveUsing<VehicleTimestampResolver>());
AutoMapper.Mapper.CreateMap<ShopLog.ViewModels.VehicleIndexViewModel, ShopLog.Models.Vehicle>().ForMember(m => m.Timestamp, opt => opt.ResolveUsing<VehicleIndexViewModelTimestampResolver>());

    public class VehicleTimestampResolver : AutoMapper.ValueResolver<Vehicle, string>
    {
        protected override string ResolveCore(Vehicle source)
        {
            return Convert.ToBase64String(source.Timestamp);
        }
    }

    public class VehicleIndexViewModelTimestampResolver : AutoMapper.ValueResolver<ShopLog.ViewModels.VehicleIndexViewModel, byte[]>
    {
        protected override byte[] ResolveCore(ShopLog.ViewModels.VehicleIndexViewModel source)
        {
            return Convert.FromBase64String(source.Timestamp);
        }
    }

查看:(注意数据键)

@(Html.Telerik().Grid(Model)
.Name("Grid")
.Columns(columns =>
{
    columns.Bound(o => o.VehicleID).Visible(false);        
    columns.Bound(o => o.VehicleName);
    columns.Bound(o => o.VehicleType);
})    
.DataBinding(dataBinding =>
    {
        dataBinding.Server().Select("Index", "Vehicle");
        dataBinding.Ajax().Select("_Index", "Vehicle").Enabled(true);
        dataBinding.Ajax().Update("_SaveVehicle", "Vehicle");
        dataBinding.Ajax().Delete("_DeleteVehicle", "Vehicle");
    })
    .Scrollable(scrolling => scrolling.Enabled(true))
    .Sortable(sorting => sorting 
        .Enabled(true)
        .OrderBy(sortOrder => sortOrder.Add(o => o.VehicleName).Ascending())
        .SortMode(GridSortMode.MultipleColumn))
    .Pageable(paging => 
        paging.Enabled(true)
        .PageSize(20)
        .Position(GridPagerPosition.Bottom))
    .Filterable(filtering => filtering.Enabled(true))
    .Groupable(grouping => grouping.Enabled(true))
    .Footer(true)
    .ToolBar(commands => commands
        .Custom()
            .HtmlAttributes(new {id = "export"})
            .Text("Export to CSV")
                .Action("ExportCsv", "Vehicle", new { page = 1, orderBy = "~", filter = "~" }))                                                     
    .Columns(columns =>
        {
            columns.Command(command =>
                {
                    command.Custom("details").Text("Details").Action("Edit", "Vehicle").HtmlAttributes(new { style = "text-align: center" }) ;
                    command.Edit().ButtonType(GridButtonType.Image);
                    command.Delete().ButtonType(GridButtonType.Image);
                }).Width(165);
        })
    .DataKeys(dataKeys => 
        {
            dataKeys.Add(key => key.Timestamp).RouteKey("Timestamp");
            dataKeys.Add(key => key.VehicleID).RouteKey("VehicleID"); 

        })
    .ClientEvents(events => events 
        .OnEdit("onEdit")
        .OnDataBound("onDataBound"))
    .ColumnContextMenu()
    .Resizable(config =>
        {
            config.Columns(true);
        })
    .Reorderable(config =>
        {
            config.Columns(true);
        })        
)

剩下的唯一事情就是弄清楚当“ViewBag.AjaxErrorMessage”返回到视图时在哪里显示它,但这不应该太难。:)

于 2012-04-12T21:15:25.440 回答