简体   繁体   中英

ASP.NET MVC, Remove [Required] on complex properties types types

I would like to make the sub properties of a complex type required ONLY in certain circunstancies. for this purpose i'm using FoolProof lib.

For instance, To register a work week schedule. I do have a POCO complex class for storing timespans like this:

[ComplexType]
class workDay{

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

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

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

}

the relevant part of the week POCO class is:

[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;}
}

As you can see, the WorkDay class is only required to be filled in if the correspondent day is true.

However the validation always require all timespans to be filled. Is somehow possible to disable a required parameter inside a sub complextype parameter based on the Week POCO class?

You cannot apply validation attributes to complex properties and get client side validation because you do not (and cannot) create a form control for a complex object (only properties of the object). You need to create a view model to represent what you want to display in the view (note the nullable properties)

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; }
    ....
}

and in the view

@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>

Then if the check box is checked, you will get a client (and server side) error it the associated StartTime , EndTime and Interval properties are not filled in (its not clear what Interval is for - the name suggests its a calculated value based on StartTime and EndTime so it may not be required in the view)

You can simplify this further and significantly reduce the amount of code in the view by adding a DayOfWeek enum property to DayScheduleVM

public DayOfWeek Day { get; set; }

so that in your GET method, you can use

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

and in the view

@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" ... />
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM