На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
  
> Заполнение поля типа DataTime значением из контроллера
    Привет.
    Не знаю точно, как сформулировать проблему.
    MVC 4.
    Модель
    класс тра-та-та
    ExpandedWrap disabled
              [DataType(DataType.Date)]
              public DateTime? BeginPeriod { get; set; }
              [DataType(DataType.Date)]
              public DateTime? EndPeriod { get; set; }

    Контроллер (заполняю поля модели значениями(в отладчике видно, что заполняются))
    ExpandedWrap disabled
      model.BeginPeriod = DateTime.Today.AddDays(-DateTime.Today.Day + 1);
                      model.EndPeriod = DateTime.Today;


    Добавлено
    Извините. Случайно нажал Enter. Все запостилось. Редактирования своего сообщения не нашел.
    Повторюсь.
    MVC 4.
    Модель
    класс тра-та-та
    ExpandedWrap disabled
      [DataType(DataType.Date)]
      public DateTime? BeginPeriod { get; set; }
      [DataType(DataType.Date)]
      public DateTime? EndPeriod { get; set; }

    Контроллер (заполняю поля модели значениями(в отладчике видно, что заполняются))
    ExpandedWrap disabled
      model.BeginPeriod = DateTime.Today.AddDays(-DateTime.Today.Day + 1);
      model.EndPeriod = DateTime.Today;
      return View(model);

    Представление
    ExpandedWrap disabled
      <td>
                              <div>
                                  Начало диапазона
                              </div>
                              <div class="editor-field">
                                  @Html.EditorFor(model => model.BeginPeriod)
                                  @Html.ValidationMessageFor(model => model.BeginPeriod)
                              </div>
                          </td>
                          <td>
                              <div>
                                  Конец диапазона
                              </div>
                              <div class="editor-field">
                                  @Html.EditorFor(model => model.EndPeriod)
                                  @Html.ValidationMessageFor(model => model.EndPeriod)
                              </div>
                          </td>

    В браузере поле, сформированное @Html.EditorFor заполнено строкой "дд.мм.гггг"
    Хотелось бы увидеть значения, записанные в контроллере.
    Если в модели убрать атрибут [DataType(DataType.Date)], то формируется простое поле редактирования с нужными данными, но хотелось бы все-таки календарь.
    Может кто может сказать, в чем дело?
    Спасибо.
    Сообщение отредактировано: Craft -
      У меня наверное будет странный вопрос, а в чем проблема? Заполнить саму модель? Или передать ее в представление (View)? Самый примитивный вариант.
      ExpandedWrap disabled
        public ActionResult Statistic()
                {
                    var model = new MyModel();
                    model.BeginPeriod = DateTime.Today.AddDays(-DateTime.Today.Day + 1);
                    model.EndPeriod = DateTime.Today;
                    return View("StatisticView", model);
                }

      Пример View
      ExpandedWrap disabled
        <div class="row">
                <div class="col-md-12">
                    <label class="control-label">С</label>
                    @Html.TextBox("BeginPeriod ", Model.BeginPeriod.Date.ToString("yyyy-MM-dd"), new { @class = "text" })
                    @if (!ViewData.ModelState.IsValid)
                    {
                        if (@ViewData.ModelState["BeginPeriod "].Errors.Count > 0)
                        {
                            <span class="field-validation-error">
                                @ViewData.ModelState["BeginPeriod "].Errors[0].ErrorMessage
                            </span>
                        }
                    }
                </div>
            </div>
            <div class="row">
                <div class="col-md-12">
                    <label class="control-label">по</label>
                    @Html.TextBox("EndPeriod", Model.EndPeriod.Date.ToString("yyyy-MM-dd"), new { @class = "text" })
                    @if (!ViewData.ModelState.IsValid)
                    {
                        if (@ViewData.ModelState["EndPeriod"].Errors.Count > 0)
                        {
                            <span class="field-validation-error">
                                @ViewData.ModelState["EndPeriod"].Errors[0].ErrorMessage
                            </span>
                        }
                    }
                </div>
            </div>

      Как то так.

      P.S. Для календарика воспользуйся для примера компонентом datepicker с bootstrapper.
      ExpandedWrap disabled
        <script src="~/Scripts/bootstrap.js"></script>
        <link href="~/Content/bootstrap.css" rel="stylesheet" />
         
        <script type="text/javascript">
            $(document).ready(function () {
                var txt = $('.text');
                txt.datepicker({
                    dateFormat: "yy-mm-dd"
                });
            });
        </script>

      Как использовать привел пример с самого верху.
      Сообщение отредактировано: Craft -
        Прошу прощения.
        Вопрос не в том, как передать модель в представление (как видите я ее передаю), а в том, почему поле ввода(редактирования) даты не заполняется значением из модели. Хотя если использовать TextBox, то поле вводя вполне себе заполняется тем, чем я хочу.
        Ваш пример, к сожалению, не смог откомпилировать. Пишу на MVC первое приложение. Максимально простое. Пытаюсь использовать стандартные элементы.
        Само по себе поле работает (выбранные данные успешно возвращаются в контроллер), просто как-то не красиво.
        Может это просто баг MVC?
          Поле выглядит так
          Прикреплённый файлПрикреплённый файл2014_05_27_15_17_22__________________________ASP.NET_MVC_____Yandex.png (2,18 Кбайт, скачиваний: 854)
            Проблема с выводом в @Html.EditorFor которую вы питаетесь использовать. Можете посмотреть на stackoverflow там такая же проблема как и у вас. Я столкнулся когда то с этой проблемой, затем мне надоела эта запара и я сделал все через TextBoxFor.
            ExpandedWrap disabled
              @Html.TextBoxFor(m => m.StartDate, new { @Value = Model.StartDate.ToString(" yyyy/MM/dd"), @class="datepicker" })

            Не заморачивайтесь так с EditorFor, там реально трабла с редактирование и отображением.
              Просто заменить EditorFor на TextBoxFor?

              При компиляции ошибка на Model.BeginPeriod.ToString("dd.MM.yyyy")
              - Ни одна из перегрузок метода "ToString" не принимает "1" аргументов

              Добавлено
              @Html.TextBoxFor дает простой Edit. Правда заполненный как надо.
              А класс @class="datepicker" надо откуда-то доустанавливать? Похоже из-за этого у меня просто Edit.
                Цитата Wovan2 @
                При компиляции ошибка на Model.BeginPeriod.ToString("dd.MM.yyyy")
                - Ни одна из перегрузок метода "ToString" не принимает "1" аргументов

                Добавлено 53 минуты назад
                @Html.TextBoxFor дает простой Edit. Правда заполненный как надо.
                А класс @class="datepicker" надо откуда-то доустанавливать? Похоже из-за этого у меня просто Edit.

                Вам нужно установить себе Bootstrapper. Или это для вас проблематично?

                Для работы с датой есть несколько вариантов. примеры
                datepicker это возможность Chrome начиная с версии 20 для работы с датами. Есть еще вариант с помощью jQuery. Посмотрите по той ссылке которую я привел. Там есть разные варианты. Я для себя брал готовое решение с библиотеки bootstrapper, и это решение у меня заработало на IE9? Firefox, Chrome и Safari. На Opera не проверял.
                Сообщение отредактировано: Craft -
                  К сожалению.
                  Ничего не понятно. Куски кода. Что - куда - откуда? Что доустанвливать? Где - что прописывать?
                  Проще никак?
                    Цитата Wovan2 @
                    К сожалению.
                    Ничего не понятно. Куски кода. Что - куда - откуда? Что доустанвливать? Где - что прописывать?
                    Проще никак?

                    Посмотри, я написал об этом статью Datapicker, Validation и другие особенности ASP.NET MVC. Там я все старался разложить по полочкам. Думаю это твой случай. Просто здесь приводить пример лень немного.
                      Спасибо.
                      Почитаю.
                        Спасибо. Прочитал. Сделал все как написано.
                        В принципе получилось. Календарик работает.
                        Но всплыла проблема с валидацией.
                        Вернее с форматом даты.
                        Везде прописал формат "dd.MM.yyyy"(в скрипте "dd.mm.yy") В поле ввода вставляется, н-р, дата 28.05.2014. При отправке в контроллер срабатывает, по видимому стандартная проверка и выводит ошибку: Поле должно содержать дату.
                        Поэкспериментировав понял, что в модель дата передается в формате "MM.dd.yyyy", в этом смысле 28.05.2014 - это непонятно что.
                        Может можно как-нибудь, либо отключить стандартную проверку, либо поменять стандартный формат?
                        Код
                        -в модели
                        [DataType(DataType.Date)]
                        [Display(Name = "Начало диапазона")]
                        [DisplayFormat(DataFormatString = "{0:dd.MM.yyyy}", ApplyFormatInEditMode = true)]
                        public DateTime BeginPeriod { get; set; }
                        -в представлении
                        <div>
                        @Html.LabelFor(m => m.BeginPeriod)
                        @Html.TextBox("BeginPeriod", Model.BeginPeriod.Date.ToString("dd.MM.yyyy"), new { @class = "text" })
                        @Html.ValidationMessageFor(model => model.BeginPeriod)
                        </div>
                        -скрипт
                        <script src="~/Scripts/jquery-ui-1.10.4.js"></script>
                        <script type="text/javascript">
                        $(document).ready(function () {
                        var txt = $('.text');
                        txt.datepicker({
                        dateFormat: "dd.mm.yy"
                        });
                        });
                        </script>

                        Добавлено
                        Вообще дата ведет себя непонятно как.
                        Если через календарь введено 01.05.2014 в модель и попадает 01.05.2014(1 мая).
                        Если через календарь введено 28.05.2014 до обработчика контроллера вообще дело не доходит.
                        Если руками набрать 05.28.2014 валидация пропускает, но в модель попадает значение 01.01.0001. Вообще хрень какая-то.
                        И где искать этот зарытый в дебри фреймворка формат?
                        В варианте с EditFor кроме того, что не отображалось начальное значение проблем то и не было. Неужели штатными средствами нельзя нормальный календарик сделать?
                          Цитата Wovan2 @
                          <script src="~/Scripts/jquery-ui-1.10.4.js"></script>
                          <script type="text/javascript">
                          $(document).ready(function () {
                          var txt = $('.text');
                          txt.datepicker({
                          dateFormat: "dd.mm.yy"
                          });
                          });
                          </script>

                          Дело в том что здесь вы указали дату
                          ExpandedWrap disabled
                            dateFormat: "dd.mm.yy"

                          А нужно указать ту которая нужна вам для вывода.
                            Если тут поменять формат, н-р на "mm.dd.yy", то в этом формате вставляется строка после выбора даты в календаре.
                            После отправки такой строки в контроллер в модели оказывается 01.01.0001. Не говоря о том, что строка даты в редакторе кувыркается туда-сюда.
                            В общем проблема где-то глубже, при переводе строки из TextBox в дату Date.
                              Давайте по порядку.
                              Цитата Wovan2 @
                              Неужели штатными средствами нельзя нормальный календарик сделать?

                              По поводу штатных средств. Какие вы видите штатные средства если type="date" появилось только в html5 input types
                              ExpandedWrap disabled
                                <input type="date" name="bday" min="2000-01-02">

                              Никто не говорит что нельзя. Но вам нужно байндинг сделать вашей модели по сути на поле input type="date". Так вот чтобы эта ерунда как то заработала под разные браузеры, добавили несколько вариантов байндинга. Один из вариантов вы могли увидеть в статье которую я привел выше, и которая основана на библиотеке jQuery. Почему jQuery, да потому что там уже сделан контрол datepicker который можно хоть как то кастомизировать. С этим контролом есть куча проблем с локализацией и т.д. Но это то решение которое я использовал в нескольких проектах, и ребята с соседних команд использовали его также. Возможно кто то знает другой вариант и подскажет вам как сделать по другому, мне будет тоже интересно узнать. Второй способ это использовать байндинг через например knockout.

                              Теперь по поводу вашей проблемы. Не хотелось бы вас расстраивать, но то как вы хотите использовать формат даты вам нужно немножко напрячься. Вам нужно будет написать кастомный байндер IModelBinder. Это не так сложно как кажется. Похожая проблема как у вас на stackoverflow. Пример использования MVC ModelBinder and Localization ну можете глянуть на всякий случай Скота Хансельмана, правда у него немного не то что вам нужно. К сожалению не знаю проще путей. Может быть UncleBob подтянется и подскажет вам что-то белее существенное, он здесь гуру в веб разработке.
                                Под штатным, я имел ввиду реализацию EditFor(почему редактор не инициализируется начальным значением).
                                А отключить валидацию как-нибудь можно? Неправильная строка (с точки зрения валидатора, н-р "01.05.2014"), нормально преобразуется в тип Data в контроллере.
                                Чтобы прочувствовать то, что Вы тут написали надо кучу времени потратить. Тем более, что в английском я практически ноль и сленг, типа, "байндинг" и пр. я тоже не понимаю. А делать надо здесь и сейчас :-(
                                Пока поднял язык С# (в смысле операторов, структур и пр.). Начал пользовать VS. Пришел из Delphi(14 лет стажа)
                                  Конечно для тех, кто знает, это ерунда, но...
                                  Проблему поборол отключив стандартную валидацию:
                                  просто закомментировал строку
                                  @*<script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>*@
                                  в представлении с элементами ввода даты.
                                  Строка формата "dd.MM.yyyy" успешно переводится в Date модели (ну об этом я уже писал).
                                  0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                  0 пользователей:


                                  Рейтинг@Mail.ru
                                  [ Script execution time: 0,0752 ]   [ 19 queries used ]   [ Generated: 23.04.24, 06:32 GMT ]