2016-09-28 79 views
0

我想只在某些circunstancies中需要複雜類型的子屬性。爲此我使用FoolProof庫。ASP.NET MVC,在複雜的屬性類型類型中刪除[必需的]

例如,要註冊一個工作周計劃。 我有用於存儲這樣的時間跨度一個POCO複雜的類:

[ComplexType] 
class workDay{ 

    [Required] 
    public TimeSpan start { get; set; } 

    [Required] 
    public TimeSpan end { get; set; } 

    [Required] 
    public TimeSpan interval { get; set; } 

} 

一週POCO類的相關部分是:

[ComplexType] 
class Week{ 

    [Required] 
    public bool monday { get; set; } 
    [RequiredIfTrue("monday")] 
    public workDay monday_timespan {get;set;} 

    [Required] 
    public bool tuesday { get; set; } 
    [RequiredIfTrue("tuesday")] 
    public workDay tuesday_timespan {get;set;} 

    // ... 

    [Required] 
    public bool sundat { get; set; } 
    [RequiredIfTrue("sunday")] 
    public workDay sunday_timespan {get;set;} 
} 

正如你所看到的,在工作日類只需要如果記者日是真實的,則填寫。

但是,驗證始終需要填寫所有時間段。是否有可能根據Week POCO類在子複雜類型參數中禁用必需的參數?

+0

此驗證是否只需要進行服務器端驗證?側? –

+1

我不認爲'FoolProof'中的'RequiredIf'適用於複雜模型,而且對於最近的一個,您的情況下的註釋也表示'workDay'註釋。嘗試將'workDay'屬性添加到'Week'類中,然後在模型綁定中處理細節。 – Hadee

+1

'[必填項(「(星期二)」]'沒有意義。格式爲'[RequiredIf(「someOtherProperty」,「ValueOfOtherProperty」)]''也許你的意思是'[RequiredIfTrue(「tuesday」)]'? –

回答

2

您不能將驗證屬性應用於複雜屬性並獲取客戶端驗證,因爲您沒有(也不能)爲複雜對象(僅限對象的屬性)創建窗體控件。你需要創建一個視圖模型來表示要在視圖中顯示(注意是空的屬性)

public class DayScheduleVM 
{ 
    public bool IsRequired { get; set; } // this will be used for conditional validation 
    [RequiredIf("IsRequired", ErrorMessage = "Please enter the start time")] 
    public TimeSpan? StartTime { get; set; } 
    [RequiredIf("IsRequired", ErrorMessage = "Please enter the end time")] 
    public TimeSpan? EndTime { get; set; } 
    [RequiredIf("IsRequired", ErrorMessage = "Please enter the interval")] 
    public TimeSpan? Interval { get; set; } 
} 
public WeekScheduleVM 
{ 
    public DayScheduleVM Sunday { get; set; } 
    public DayScheduleVM Monday { get; set; } 
    .... 
} 

什麼,並在視圖

@model WeekScheduleVM 
.... 
@using (Html.BeginForm()) 
{ 
    <table> 
     .... 
     <tbody> 
      <tr> 
       <td>@Html.DisplayNameFor(m => m.Sunday)</td> 
       <td>@Html.CheckBoxFor(m => Sunday.IsRequired)</td> 
       <td> 
        @Html.TextBoxFor(m => Sunday.StartTime) 
        @Html.ValidationMessageFor(m => Sunday.StartTime) 
       </td> 
       .... // ditto for EndTime and Interval 
      </tr> 
      <tr> 
       .... // ditto for Monday,Tuesday etc 
      </tr> 

這時如果複選框被選中,你將得到一個客戶端(和服務器端)的錯誤,它關聯的StartTime,EndTimeInterval屬性未填寫(其不清楚Interval的用途 - 名稱暗示其計算值基於StartTimeEndTime,因此可能不需要在視圖中)

您可以在此進一步簡化並通過添加DayOfWeek枚舉屬性顯著減少代碼量在視圖中DayScheduleVM

public DayOfWeek Day { get; set; } 

,這樣在你的GET方法,您可以使用

List<DayScheduleVM> model = new List<DayScheduleVM>(); 
foreach (var day in Enum.GetValues(typeof(DayOfWeek))) 
{ 
    days.Add(new DayScheduleVM { Day = (DayOfWeek)day }); 
} 
return View(model); 

並在視圖中

@model List<DayScheduleVM> 
.... 
@using (Html.BeginForm()) 
{ 
    <table> 
     .... 
     <tbody> 
      @for(int i = 0; i < Model.Count; i++) 
      { 
       <tr> 
        <td>@Html.DisplayFor(m => m[i].Day)</td> 
        <td>@Html.CheckBoxFor(m => m[i].IsRequired)</td> 
        <td> 
         @Html.TextboxFor(m => m[i].StartTime) 
         @Html.ValidationMessageFor(m => m[i].StartTime) 
        </td> 
        .... // ditto for `EndTime` and `Interval` 
       </tr> 
      } 
     </tbody> 
    </table> 
    <input type="submit" ... /> 
}