我正在创建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;
}
答案 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));
}