2017-05-04 51 views
0

我在我的视图模型中调用了三个模型(Unit,Site,Work_Type),名为UnitAdminViewModel。我需要从单元模型中根据需要设置一个字段。因为我使用的是数据库优先方法,所以我无法直接修改单元模型,因为它会自动生成。我怎样才能成功添加:ASP.NET MVC 5 - 如何在ViewModel中添加[必需的]数据注释

[Required(ErrorMessage = "Group is required")] public string GroupName { get; set; }

到我的视图模型UnitAdminViewModel?

public class UnitAdminViewModel 
{ 
    public Unit Unit { get; set; } 
    public List<Site> Site { get; set; } 
    public IEnumerable<Work_Type> Work_Type { get; set; } 
} 

在机组型号,我想设置现场的groupName [必需]

public partial class Unit 
{ 
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")] 
    public Unit() 
    { 
     this.Staffs = new HashSet<Staff>(); 
    } 

    public int UnitID { get; set; } 
    public string UnitCode { get; set; } 
    public string UnitName { get; set; } 
    public string GroupName { get; set; } 
    public byte IncentiveUnit { get; set; } 
    public bool CallCenter { get; set; } 
    public bool CDWUnit { get; set; } 
    public string CDWSite { get; set; } 
    public Nullable<int> SiteID { get; set; } 
    public Nullable<int> DivisionID { get; set; } 
    public bool WFCUnit { get; set; } 
    public bool QAMonitored { get; set; } 
    public bool NICEMonitored { get; set; } 
    public string ListPrefix { get; set; } 
    public string TSHSource { get; set; } 
    public string StatsSource { get; set; } 
    public string DialerSource { get; set; } 
    public Nullable<int> CostCenterID { get; set; } 
    public int WaterfallView { get; set; } 
    public bool Locked { get; set; } 
    public string Platform { get; set; } 
    public Nullable<int> Supplier { get; set; } 
    public string Work_Type { get; set; } 

    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")] 
    public virtual ICollection<Staff> Staffs { get; set; } 
} 

更新


我试图去关@Izzy例子。我觉得我更接近,但[必填]仍然不会触发验证错误,当我提交表单没有填充该字段。 @Izzy,有什么我可能会失踪?

视图模型

public class UnitAdminViewModel 
{ 
    public Unit Unit { get; set; } 
    public List<Site> Site { get; set; } 
    public IEnumerable<Work_Type> Work_Type { get; set; } 

} 

UnitMetaData类

[MetadataType(typeof(UnitMetaData))] 
    public partial class Unit 
    { 

    } 

    public class UnitMetaData { 
     [Required(ErrorMessage = "Group is required")] 
     public string GroupName { get; set; } 

     [Required(ErrorMessage = "UnitName is required")] 
     public string UnitName { get; set; } 

     public string CDWSite { get; set; } 

     public string Platform { get; set; } 

     public Nullable<int> Supplier { get; set; } 

     public string Work_Type { get; set; } 
} 

VIEW

@model WebReportingToolDAL.Models.ViewModels.UnitAdminViewModel 

@{ 
    ViewBag.Title = "Create"; 
    Layout = "~/Views/Shared/_Layout.cshtml"; 
} 

<h2>Create</h2> 

@using (Html.BeginForm()) 
{ 
    @Html.AntiForgeryToken() 

<div class="form-horizontal"> 
    <h4>Unit</h4> 
    <hr /> 
    @Html.ValidationSummary(true, "", new { @class = "text-danger" }) 

    <div class="form-group"> 
     @Html.LabelFor(model => model.Unit.UnitName, htmlAttributes: new { @class = "control-label col-md-2" }) 
     <div class="col-md-10"> 
      @Html.EditorFor(model => model.Unit.UnitName, new { htmlAttributes = new { @class = "form-control" } }) 
      @Html.ValidationMessageFor(model => model.Unit.UnitName, "", new { @class = "text-danger" }) 
     </div> 
    </div> 

    <div class="form-group"> 
     @Html.LabelFor(model => model.Unit.GroupName, htmlAttributes: new { @class = "control-label col-md-2" }) 
     <div class="col-md-10"> 
      @Html.EditorFor(model => model.Unit.GroupName, new { htmlAttributes = new { @class = "form-control" } }) 
      @Html.ValidationMessageFor(model => model.Unit.GroupName, "", new { @class = "text-danger" }) 
     </div> 
    </div> 

    <div class="form-group"> 
     @Html.LabelFor(model => model.Unit.CDWSite, htmlAttributes: new { @class = "control-label col-md-2" }) 
     <div class="col-md-10"> 
      @Html.DropDownListFor(model => model.Unit.CDWSite, new SelectList(Model.Site, "SiteName", "SiteName"), new { @class = "form-control" }) 
     </div> 
    </div> 

    <div class="form-group"> 
     @Html.LabelFor(model => model.Unit.Platform, htmlAttributes: new { @class = "control-label col-md-2" }) 
     <div class="col-md-10"> 
      @Html.DropDownListFor(model => model.Unit.Platform, new List<SelectListItem> { new SelectListItem { Text = "PSCC", Value = "PSCC" }, new SelectListItem { Text = "RC", Value = "RC" } }, new { @class = "form-control" }) 
     </div> 
    </div> 

    <div class="form-group"> 
     @Html.LabelFor(model => model.Unit.Supplier, htmlAttributes: new { @class = "control-label col-md-2" }) 
     <div class="col-md-10"> 
      @Html.DropDownListFor(model => model.Unit.Supplier, new List<SelectListItem> { new SelectListItem { Text = "0", Value = "0" }, new SelectListItem { Text = "1", Value = "1" } }, new { @class = "form-control" }) 
     </div> 
    </div> 

    <div class="form-group"> 
     @Html.LabelFor(model => model.Unit.Work_Type, htmlAttributes: new { @class = "control-label col-md-2" }) 
     <div class="col-md-10"> 
      @Html.DropDownListFor(model => model.Unit.Work_Type,new SelectList(Model.Work_Type, "Name", "Name"),new { @class = "form-control" }) 
     </div> 
    </div> 

    <div class="form-group"> 
     <div class="col-md-offset-2 col-md-10"> 
      <input type="submit" value="Create" class="btn btn-default" /> 
     </div> 
    </div> 
</div> 
} 

控制器

​​
+0

对我来说,它看起来像你正在使用实体,这真的是其他ORM像Dapper一样闪耀的地方。使用实体,您必须将对象的属性复制到您的“模型”并在其中添加[必需的]数据注释。当将其保存回数据库时,请将其复制回POCO并保存。使用Dapper,您可以简单地创建一个从您的数据库表建模的POCO类,并将您的数据注释添加到其中。 –

+0

难道你不需要/需要一个UnitViewModel吗?因为这将是添加属性的正确且合乎逻辑的位置。 –

+0

@KevinBBurns - 所有这些优势同样适用于EF,并且也是代码优先。这只是数据库优先的结果。 –

回答

3

当使用数据库第一种方法,你会意识到类被标记为partial所以你可以做的是利用MetadataType属性来实现你以后。

因此,请继续创建一个文件并将其命名为例如UnitMetaData。您的代码应该是这个样子:

public class UnitMetaData 
{ 
    [Required(ErrorMessage = "Group is required")] 
    public string GroupName { get; set; } 
    //more properties 
} 

Unit类是局部的,所以你可以创建它的另一个文件,并使用MetadataType为:

[MetadataType(typeof(UnitMetaData))] 
public partial class Unit 
{ 
} 

更多MetadataTypehere

partial定义:

It is possible to split the definition of a class or a struct, an interface or a method over two or more source files. Each source file contains a section of the type or method definition, and all parts are combined when the application is compiled.

source

请注意:确保namespace是一样的生成Unit类,否则将无法正常工作

+0

感谢您的详细介绍,@Izzy。我现在正在使用您的回复来查看我是否可以将此工作。有一个问题,当你有更多的属性在你的UnitMetaData类的例子中列出。你是否说我需要添加我的其他属性?或者我可以只添加GroupName,如果这是我需要的唯一一个? – GRU119

+0

我看到了关于拆分类的定义的第二个注释。所以我认为这是一个是的呢? – GRU119

+0

@ GRU119不客气!您不必添加所有需要'DataAnnotations'的属性。 @Chris回答他也有一个非常有效的观点。 – Izzy

1

您可以使用真正的视图模型,换一个。简单地将一堆实体包装在一个类中就是缺少什么视图模型的重点。您的视图模型应该只包含应该显示/编辑的属性,并且应该包含视图的业务逻辑,例如GroupName是必需的(当它显然不在数据库级别时)。

这意味着创建类似:

public class UnitViewModel 
{ 
    // other properties you want to edit 

    [Required] 
    public string GroupName { get; set; } 
} 

然后,您在您的视图中使用这个而不是Unit,并从UnitViewModel张贴的属性映射到您的Unit实例。

+0

你让我对数据库级这个领域感到好奇。我检查了。数据库中的GroupName不能为空。这就是说,它在数据库级是必需的。由于它在数据库级别是必需的,你知道EF为什么不尊重这个吗?你会认为自动生成的模型会有[必须的]注释已经存在吗?这个问题的重点是...当我在Web表单上创建一个新记录时,如果提交时没有填写它,我希望验证说“组名是必需的”。我甚至需要[必须的]注释来做到这一点? – GRU119