存储时间控制器和视图显示和保存

时间:2018-02-21 21:48:47

标签: asp.net-mvc model-view-controller asp.net-mvc-5

我有以下类设置(部分取自Store open days and times):

public class Location {
    [Key]
    public virtual int Id { get; set; }
    public virtual string Name { get; set; }
    public virtual ICollection<LocationTime> LocationTimes { get; set; }
}

public class LocationTime {
    [Key]
    public virtual int Id { get; set; }
    public virtual int LocationId { get; set; }
    [ForeignKey("LocationId")]
    public virtual Location Location { get; set; }
    public virtual int TimeId { get; set; }
    [ForeignKey("TimeId")]
    public virtual Time Time { get; set; }
}

public class Time {
    public Time(DayOfWeek day, string openTime, string closeTime) {
        Day = day;
        OpenTime = openTime ?? "0000";
        CloseTime = closeTime ?? "0000";
    }

    [Key]
    public virtual int Id { get; set; }
    public virtual DayOfWeek Day { get; private set; }
    public virtual string OpenTime { get; private set; }
    public virtual string CloseTime { get; private set; }
    public virtual IEnumerable<LocationTime> LocationTImes { get; set; }

    public override string ToString() {
        return $"{Day} : {OpenTime} to {CloseTime}";
    }
}

我想弄清楚的是如何最好地编写我的控制器和视图以显示如下,确保尊重任何模型绑定,验证等。See dotnetfiddle

StoreHours screenshot

目前,如果选择了Time,我不打算保存Closed值,并且当没有价值时让应用暗示Closed,但我不确定我喜欢这个想法。

此外,样本中的时间间隔为30分钟,这可以/将通过某些应用设置更改,因此我不想对此进行硬编码。

如果您需要更多信息,请告诉我。

感谢。

1 个答案:

答案 0 :(得分:1)

您遇到的第一个问题是您的'时间'是string。虽然.NET的时间不是很好,但使用TimeSpan是一个更好的选择,并且将映射到SqlServer TIME数据类型。

您的观点模型应为

public class LocationTimesCollectionVM
{
    public IEnumerable<SelectListItem> TimeOptions { get; set; }
    public IEnumerable<LocationTimesVM> Days { get; set; }
}
public class LocationTimesVM
{
    public DayOfWeek Day { get; set; }
    [RequiredIfNotEmpty("ClosingTime", ErrorMessage = "An opening time is required if a closing time is specified")]
    public TimeSpan? OpeningTime { get; set; }
    [RequiredIfNotEmpty("OpeningTime", ErrorMessage = "An closing time is required if a opening time is specified")]
    [NotEqualTo("OpeningTime", ErrorMessage = "The closing time cannot equal the opening time")]
    public TimeSpan? ClosingTime { get; set; }
    [DisplayFormat(DataFormatString = "{0:hh\\:mm}")]
    public TimeSpan? OpeningHours { get; set; }
}

请注意,OpeningHours属性是可选的,但包含计算的开放时间并将其显示在视图中可能很有用(并在OpeningTime或{{1时使用javascript更新其值已被选中。

我还在foolproof库中包含了一些建议的条件验证属性,用于验证值

然后GET方法(对于ClosingTime方法)

Create

您的观点(public ActionResult Create() { LocationTimesCollectionVM model = new LocationTimesCollectionVM { Days = Enum.GetValues(typeof(DayOfWeek)).Cast<DayOfWeek>().Select(x => new LocationTimesVM { Day = x } }; ConfigureViewModel(model); return View(model); } [HttpPost] public ActionResult Create(LocationTimesCollectionVM model) { if (!ModelState.IsValid) { ConfigureViewModel(model); return View(model); } // ... initialize data models from view model, save and redirect. } private void ConfigureViewModel(LocationTimesCollectionVM model) { // Generate the SelectList int increment = 30; // This would be your stored value (i.e. 15 or 30 or 60 min intervals) TimeSpan interval = new TimeSpan(0, increment, 0); TimeSpan time = new TimeSpan(0, 0, 0); TimeSpan max = new TimeSpan(23, 59, 59); List<SelectListItem> timeOptions = new List<SelectListItem>(); while (time < max) { timeOptions.Add(new SelectListItem { Value = time.ToString(), Text = new DateTime(time.Ticks).ToString("t") }); time = time.Add(interval); } model.TimeOptions = timeOptions; } )将是

Create.cshtml

需要位于@model LocationTimesCollectionVM .... @using (Html.BeginForm()) { .... <table> <thead> ... </thead> <tbody> @Html.EditorFor(m => m.Days, new { TimeOptions = Model.TimeOptions }) </tbody> </table> .... } 文件夹中的EditorTemplate LocationTimesVM,并命名为/Views/Shared/EditorTemplates/

LocationTimesVM.cshtml