ASP.在复杂的属性类型上移除[Required]

本文关键字:Required 类型 复杂 属性 ASP | 更新日期: 2023-09-27 18:09:04

我想使复杂类型的子属性只在某些情况下需要。为此,我使用了傻瓜库。

例如,注册一个工作周计划。我确实有一个用于存储时间跨度的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;}
}

可以看到,只有在对应的日期为真时才需要填写WorkDay类。

然而,验证总是要求填充所有的时间跨度。是否有可能在基于Week POCO类的子复杂类型参数中禁用所需参数?

ASP.在复杂的属性类型上移除[Required]

您不能将验证属性应用于复杂属性并获得客户端验证,因为您不能(也不能)为复杂对象创建表单控件(只能创建对象的属性)。您需要创建一个视图模型来表示您想要在视图中显示的内容(注意可空属性)

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的计算值,所以它可能不需要在视图中)

通过向DayScheduleVM

添加DayOfWeek枚举属性,可以进一步简化这一点,并显著减少视图中的代码量。
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" ... />
}