2017-05-04 34 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