Привязка часов, минут и секунд промежутка времени отдельно к модели asp.net ядро

#asp.net-core

Вопрос:

Я должен ввести часы, минуты и секунды в форму и использовать для этого 3 ввода

 @model LearnWebsite.Dtos.Course.CourseDTO

<div class="form-group ">
   <label class="" asp-for="Duration"></label>
   <div class="flex-container text-center mr-5">
     <input class="form-control" asp-for="Duration.Hours"/>
     <input class="form-control" asp-for="Duration.Minutes"/>
     <input class="form-control" asp-for="Duration.Seconds"/>
   </div>
</div>
 

Модель обладает таким свойством, как это

продолжительность публичного промежутка времени { получить; установить; }

И контроллер такой

 [HttpPost]
[AutoValidateAntiforgeryToken]
public async Task<IActionResult> CreateAsync(CourseDTO dTO)
{
}
 

Но свойство продолжительности не привязывается должным образом

Продолжительность часа, мин и Сек равна 0

Комментарии:

1. Я думаю, это потому, что свойство TimeSpan «Часы», «Минуты» и «секунды» доступно только для чтения и не может быть установлено напрямую. dTO.Продолжительность = Промежуток времени. От часов(Конвертировать. ToInt32(Запрос. Форма[«Продолжительность. Часов»])); Это работает правильно.

Ответ №1:

Вы можете попробовать использовать следующие методы, чтобы получить значение временного интервала.

  1. Использование jQuery

    На странице просмотра добавьте скрытое поле:

      <div class="form-group ">
         <label class="" asp-for="Duration"></label>
         <div class="flex-container text-center mr-5">
             <input class="form-control" asp-for="Duration" type="hidden"/>
             <input class="form-control Durationhours" asp-for="Duration.Hours" />
             <input class="form-control Durationminutes" asp-for="Duration.Minutes" />
             <input class="form-control Durationseconds" asp-for="Duration.Seconds" />
         </div>
     </div>
     

    Затем используйте следующий сценарий jQuery: после ввода пользователем значения сохраните значение в скрытом поле

      @section Scripts {
         @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
    
         <script>
             $(function () {
    
                 $(".Durationhours, .Durationminutes, .Durationseconds").change(function () {
                     var hrs = $(".Durationhours").val() || 0;
                     var min = $(".Durationminutes").val() || 0;
                     var sec = $(".Durationseconds").val() || 0; 
                     $("#Duration").val(hrs   ":"   min   ":"   sec);
                 });
    
             });
         </script>
     }
     

    Затем результат, как показано ниже:

    введите описание изображения здесь

  2. В контроллере получите интервал времени с помощью Request.Form() метода.

    В контроллере код, как показано ниже:

      [HttpPost]
     [AutoValidateAntiforgeryToken]
     public IActionResult CreateCourse(CourseDTO dTO)
     {
         dTO.Duration  = TimeSpan.FromHours(Convert.ToInt32(Request.Form["Duration.Hours"]));
         dTO.Duration  = TimeSpan.FromMinutes(Convert.ToInt32(Request.Form["Duration.Minutes"]));
         dTO.Duration  = TimeSpan.FromSeconds(Convert.ToInt32(Request.Form["Duration.Seconds"]));
    
         if (ModelState.IsValid)
         {
    
         }
         return View();
     }
     

    результат такой:

    введите описание изображения здесь

  3. Использование пользовательского модельбиндера

    Создайте модельбиндер курса:

      public class CourseDTOModelBinder : IModelBinder
     {
         public Task BindModelAsync(ModelBindingContext bindingContext)
         {
             if (bindingContext == null)
                 throw new ArgumentNullException(nameof(bindingContext));
    
             var name = bindingContext.ValueProvider.GetValue("CourseName").FirstValue;
             if (name.Length == 0)
                 return Task.CompletedTask;
    
             var hrs = bindingContext.ValueProvider.GetValue("Duration.Hours").FirstValue;
             var min = bindingContext.ValueProvider.GetValue("Duration.Minutes").FirstValue;
             var sec = bindingContext.ValueProvider.GetValue("Duration.Seconds").FirstValue;
    
             var result = new CourseDTO
             {
                 CourseName = name,
                 Duration = TimeSpan.FromHours(Convert.ToInt32(hrs))   TimeSpan.FromMinutes(Convert.ToInt32(min))   TimeSpan.FromSeconds(Convert.ToInt32(sec)) 
             };
             bindingContext.Result = ModelBindingResult.Success(result); 
    
             return Task.CompletedTask;
         }
     }
     

    Затем примените атрибут CourseDTOModelBinder к модели и методу действия:

      [ModelBinder(BinderType = typeof(CourseDTOModelBinder))]
     public class CourseDTO
     {
         public string CourseName { get; set; } 
         public TimeSpan Duration { get; set; }
     }
    
     [HttpPost]
     [AutoValidateAntiforgeryToken]
     public IActionResult CreateCourse([ModelBinder(BinderType = typeof(CourseDTOModelBinder))] CourseDTO dTO)
     {  
         if (ModelState.IsValid)
         {
    
         }
         return View();
     }
     

    Результат, как показано ниже:

    введите описание изображения здесь