在MVC中处理模型和视图模型

时间:2017-03-17 12:42:58

标签: asp.net-mvc asp.net-mvc-5 kendo-grid

我正在创建MVC应用程序,并且在我的应用程序中有关于使用视图模型和模型的问题。

我在视图模型中有额外的字段要显示在屏幕上,而我需要在保存记录时只发送一些字段。例如,请参阅下面的代码

视图模型

  public class Team 
        {
            public int TeamID { get; set; }
            public string CountryCode { get; set; }
            public string TeamName { get; set; }
            public string TeamDescription { get; set; }
            public DateTimeOffset CreatedDate { get; set; }
            public string CreatedBy { get; set; }
            public DateTimeOffset? ModifiedDate { get; set; }
            public string ModifiedBy { get; set; }
        }

我需要在视图上显示CreatedDate,CreatedBy,ModifiedDate,ModifiedBy字段。

我有另一个名为TeamIn的模型,我希望在保存记录时使用它。这不包含CreatedDate,CreatedBy,ModifiedDate,ModifiedBy。

字段
public class TeamIn : BaseEntity
    {
        [ScaffoldColumn(false)]
        public int TeamID { get; set; }

        [Display(Name = "Country Code")]
        public string CountryCode { get; set; }
        [Display(Name = "Team Name")]
        public string TeamName { get; set; }
        [Display(Name = "Team Description")]
        public string TeamDescription { get; set; }

    }

  public abstract class BaseEntity
    {

        public DateTimeOffset CreatedDate { get; set; }

        public string CreatedBy { get; set; }

        public DateTimeOffset ModifiedDate { get; set; }

        public string ModifiedBy { get; set; }
    }

然而,我的视图引用了TeamIn模型,该模型当前包含我需要显示的所有字段。但是我不想在保存和/或更新时传递reatedDate,CreatedBy,ModifiedDate,ModifiedBy。有人可以告诉我最好的方法吗

查看

@model IEnumerable<CC.GRP.MCRequest.Models.TeamIn>
@Html.Partial("~/Views/Admin/_AdminMenu.cshtml");


@{
    ViewBag.Title = "MCR Team Administration";
}


<div class="grids" id="teamGrid">


    @(Html.Kendo().Grid<CC.GRP.MCRequest.Models.TeamIn>()
    .Name("GridTeam")
    .Columns(columns =>
    {
        columns.Bound(o => o.TeamID).Hidden();
        columns.Bound(o => o.CountryCode);
        columns.Bound(o => o.TeamName);
        columns.Bound(o => o.TeamDescription);
        columns.Bound(o => o.CreatedBy);
        columns.Bound(o => o.CreatedDate);
        columns.Bound(o => o.ModifiedBy);
        columns.Bound(o => o.ModifiedDate);
        columns.Command(command => { command.Edit(); command.Destroy(); }).Width(250);
    })
    .ToolBar(toolbar => toolbar.Create())
     .Editable(editable => editable.Mode(GridEditMode.PopUp)
     .TemplateName("TeamEdit")
        .Window(w => w.Width(500))
     )
    .Pageable()
    .Sortable()
    .Filterable()
    .Scrollable()
    .Groupable()
    .DataSource(dataSource => dataSource
        .Ajax()
        .Model(model => model.Id(t => t.TeamID))
        .Create(create => create.Action("Team_Create", "Admin"))
        .Read(read => read.Action("Team_Read", "Admin"))
        .Update(update => update.Action("Team_Update", "Admin"))
        .Destroy(delete => delete.Action("Team_Delete", "Admin"))
    )
    )

创建控制器

 [HttpPost]
        public ActionResult Team_Create([DataSourceRequest] DataSourceRequest request, Team team)
        {

            if (!ModelState.IsValid)
            {
                return null;
            }

            if (team.TeamID == 0)
            {
                mcrRepository.CreateTeam(team);
                return Json(mcrRepository.GetTeams().ToDataSourceResult(request));
            }
            else
            {
                mcrRepository.UpdateTeam(team);
            }
            return null;


        }

读取控制器

public ActionResult Team_Read([DataSourceRequest]DataSourceRequest request)
    {
         return Json(mcrRepository.GetTeams().ToDataSourceResult(request), JsonRequestBehavior.AllowGet);
    }

 [HttpPost]
        public ActionResult Team_Create([DataSourceRequest] DataSourceRequest request, TeamIn team)
        {

            if (!ModelState.IsValid)
            {
                return null;
            }

            if (team.TeamID == 0)
            {
                mcrRepository.CreateTeam(team);
                return Json(mcrRepository.GetTeams().ToDataSourceResult(request));
            }
            else
            {
                mcrRepository.UpdateTeam(team);
            }
            return null;


        }

2 个答案:

答案 0 :(得分:1)

  

我不想传递reatedDate,CreatedBy,ModifiedDate,ModifiedBy   在保存和/或更新时。有人能告诉我最好的方法   做到这一点

个人不喜欢在View中使用Entity / Domain类。 主要是,我不想用在视图中用于验证的数据注释来装饰实体/域类。

正如您所说,Team是一个ViewModel。然后在View中使用它。如果它不满足View的要求,则创建另一个ViewModel类。

GitHub的示例项目中, User View 使用 UserModel < / strong>与 User 实体不同。

@(Html.Kendo().Grid<UserModel>()
   .Name("userGrid")
   .Sortable()
   .Pageable(pageableBuilder => pageableBuilder.Refresh(true)
         .PageSizes(new[] { 5, 10, 25, 50, 100, 500, 1000 }))
   .Columns(columns =>
   {
       ...
   })
   .DataSource(dataSource => dataSource
       .Ajax()
       .ServerOperation(true)
       .PageSize(10)
       .Read(read => read.Action("List", "Users").Data("additionalData"))
       .Model(model => model.Id(m => m.Id))
       .Events(events => events
      .RequestStart("requestStart")
      .RequestEnd("requestEnd")
      .Error("displayGridError")))

   )

仅供参考:我使用 AutoMapper 将实体/域映射到ViewModel,反之亦然。使用AutoMapper时,您可以在映射为this时指定要忽略的属性。

答案 1 :(得分:0)

Win的回答很明显,但是为了扩充我的评论,这是我使用Automapper 4.1的示例,在其他版本中语法为.Project().To<MyViewModel>()

using AutoMapper;
using AutoMapper.QueryableExtensions;

public JsonResult ReadMyStuff([DataSourceRequest] DataSourceRequest request)
{
    var myStuffListVM = _db.MyStuffs
             .Where(m => m.Type == "XXX")
             .ProjectTo<MyStuffViewModel>();
    var response = myStuffListVM.ToDataSourceResult(request);
    return Json(response, JsonRequestBehavior.AllowGet);
}

编辑:对于更新,只需按@Win建议的那样撤消该过程。去获取实体模型并替换视图模型更改。剑道会知道你正在传递视图模型,所以你的创建和更新都很好:

public ActionResult Add([DataSourceRequest] DataSourceRequest request, MyStuffViewModel myVM)
{
    if (myVM != null && ModelState.IsValid)
    {
        var myEntity = Mapper.Map<MyEntity>(myVM);
        _db.Applications.Add(myEntity);
        _db.SaveChanges();
    }
    return Json(new[] { myVM }.ToDataSourceResult(request, ModelState));
}