2013-11-27 4 views
1

У меня проблемы с обучением C# и mvc4.C# MVC 4 ViewModel не принимает значение null DateTime

Проблема возникает в части фильтра моего приложения. У меня есть ViewModel, который захватывает список «Listar_Produtos» базы данных и некоторые поля для поиска параметров.

Что я намерен сделать, так это сделать фильтр приемлемым для любого поля, даже если это нулевые значения. Потому что я сделаю фильтр на основе этих параметров.

У меня есть ViewModel:

using Foolproof; 
using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.ComponentModel.DataAnnotations; 
using System.Linq; 
using System.Web; 

namespace Ecommerce.Models.Repository 
{ 
    public class Produto_Repository 
    { 
     public class Index_Listar_Produtos 
     { 
      public List<Listar_Produto> Index_List_Produto { get; set; } 

      [Display(Name = "Data de Cadastro Inicial")] 
      [DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:dd/MM/yyyy}")] 
      public Nullable<DateTime> CadastroInicialData { get; set; } 

      [Display(Name = "Data de Cadastro Final")] 
      [DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:dd/MM/yyyy}")] 
      [GreaterThanOrEqualTo("CadastroInicialData", ErrorMessage = "\"Data Inicial\", deve ser maior que \"Data Final\"")] 
      public Nullable<DateTime> CadastroFinalData { get; set; } 
     } 
    } 
} 

И у меня есть следующий вид:

<td> 
    @Html.LabelFor(Model => Model.CadastroInicialData)<br /> 
    @Html.TextBoxFor(Model => Model.CadastroInicialData, "{0:dd/MM/yyyy}") 
    @Html.ValidationMessageFor(Model => Model.CadastroInicialData) 
</td> 
<td> 
    @Html.LabelFor(Model => Model.CadastroFinalData)<br /> 
    @Html.TextBoxFor(Model => Model.CadastroFinalData, "{0:dd/MM/yyyy}") 
    @Html.ValidationMessageFor(Model => Model.CadastroFinalData) 
</td> 

В моем контроллере у меня есть:

[AcceptVerbs(HttpVerbs.Get)] 
public ActionResult Filtro(Produto_Repository.Index_Listar_Produtos ViewModel) 
{ 
    if (!ModelState.IsValid) 
    { 
     Produto_Repository.Index_Listar_Produtos Model_list = Produto_Repository.GetProdutoByAll(); 
     ViewModel.Index_List_Produto = Model_list.Index_List_Produto; 
     return View("Index", ViewModel); 
    } 
} 

Где «Produto_Repository.GetProdutoByAll() ;» снова возвращает список «Produtos».

Код работает отлично и хорошо, если я даю даты в форме. Даты указаны в формате «pt-BR»: 23/03/2013.

Но если я не предоставляю ничего в полях (оба поля даты в моем представлении), чем «if (! ModelState.IsValid)» возвращает true и вводит «if», потому что появляются как «CadastroInicialData», так и «CadastroFinalData» с нулевыми значениями

Желаемое поведение заключается в том, что ViewModel может принимать нулевые или пустые значения, предоставленные «Nullable» или «DateTime?».

I судимого для вставки значений в обнуляемое полей даты, выполнив следующие действия:

if (ViewModel.CadastroInicialData == null) 
    ViewModel.CadastroInicialData = Convert.ToDateTime("01/01/2013"); 
if (ViewModel.CadastroFinalData == null) 
    ViewModel.CadastroFinalData = Convert.ToDateTime("01/01/2013"); 

Но теперь ViewModel возвращает следующее сообщение об ошибке: «неверный формат дата»

Одно замечания, что Я использую следующее «решение» для преобразования данных для pt-BR dateformat по следующему вопросу: Format datetime in asp.net mvc 4

Как я могу заставить ViewModel принимать значения null whe n текстовые поля не заполняются датами? Я немного смущен. Я приветствую любую помощь! Благодаря !

+0

Это аннотации данных, пожалуйста, взгляните на мой ответ, чтобы понять, почему. – Tommy

+0

hi @Tommy, помощник аннотаций данных - это «GreaterThanOrEqualTo», а не «GreaterThan». Если время datetime равно нулю, проверка будет успешной. – Lin

+0

... вы на 100%? Какова ошибка при проверке состояния модели? – Tommy

ответ

1

Вы можете добавить еще свойства в класс модели, а затем использовать их, чтобы определить, если значение равно нулю или нет. Также имейте это в виду.Смотрите ниже код:

Модель

public class Index_Listar_Produtos 
{ 
    public List<Listar_Produto> Index_List_Produto { get; set; } 

    [Display(Name = "Data de Cadastro Inicial")] 
    [DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:dd/MM/yyyy}")] 
    public Nullable<DateTime> CadastroInicialData { get; set; } 

    [Display(Name = "Data de Cadastro Final")] 
    [DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:dd/MM/yyyy}")] 
    [GreaterThanOrEqualTo("CadastroInicialData", ErrorMessage = "\"Data Inicial\", deve ser maior que \"Data Final\"")] 
    public Nullable<DateTime> CadastroFinalData { get; set; } 


    public string GetStringTypeCadastroInicialData 
    { 
     get { return CadastroInicialData != null ? CadastroInicialData.Value.ToShortDateString() : DateTime.MinValue.ToShortDateString()(Or empty string); } 
    } 

    public string GetStringTypeCadastroFinalData 
    { 
     get { return CadastroInicialData != null ? CadastroFinalData.Value.ToShortDateString() : DateTime.Now.ToShortDateString(); } 
    } 

} 

Посмотреть

<td> 
    @Html.LabelFor(Model => Model.GetStringTypeCadastroInicialData)<br /> 
    @Html.TextBoxFor(Model => Model.GetStringTypeCadastroInicialData) 
    @Html.ValidationMessageFor(Model => Model.GetStringTypeCadastroInicialData) 
</td> 
<td> 
    @Html.LabelFor(Model => Model.GetStringTypeCadastroFinalData)<br /> 
    @Html.TextBoxFor(Model => Model.GetStringTypeCadastroFinalData) 
    @Html.ValidationMessageFor(Model => Model.GetStringTypeCadastroFinalData) 
</td> 
+0

Лин, спасибо за ответ. Ваш код почти сохраняет мой день, единственное, что «неправильно» - это то, что TextBoxFor «устанавливается» по умолчанию, когда я вхожу на страницу (потому что к этому времени значение равно null). Текстовое поле представляет собой вход для интервала поиска и не может начать заполняться. Только в контроллере было бы здорово, если бы значение nulls могло быть преобразовано. –

+0

@MarcosSantini, я думаю, если к моменту использования «" вместо «" 01/01/2013 значение «null» равно нулю, вам также не нужно использовать «{0: dd/MM/yyyy}», Datetime formater в TextBoxFor. Позвольте мне уточнить это. – Lin

+0

Лин, только что заметил, что это неправильно. «Get {return CadastroInicialData! = Null? CadastroFinalData.Value.ToShortDateString(): ""; } «никогда не будет затронута, потому что представление попытается установить« GetStringTypeCadastroInicialData », и CadastroFinalData никогда не будет изменен пользователем, пытающимся найти что-либо! = ( –

2

Вместо

public Nullable<DateTime> CadastroInicialData { get; set; } 

попробовать

public DateTime? CadastroInicialData { get; set; } 

, а затем, чтобы увидеть, если это имеет значение, вы можете сделать:

if (CadastroInicialData.HasValue) 
{ 
    // do your processing here 
} 
+6

Это не поможет! DateTime? равен Nullable , и я использовал оба синтакса без какого-либо продвижения. И это не решает мою проблему, которая пропускает значения Nable с помощью ModelView в Controlller. = P –

0

Вместо использования Convert.ToDateTime использовать DateTime .TryParseExact, и вы можете указать формат и культуру. Ниже код должен работать и исправлять ошибки:

if (ViewModel.CadastroInicialData == null) 
    ViewModel.CadastroInicialData = DateTime.TryParseExact(text, "MM/dd/yyyy", 
          CultureInfo.InvariantCulture, 
          DateTimeStyles.None, 
          out "01/01/2013"); 
if (ViewModel.CadastroFinalData == null) 
    ViewModel.CadastroFinalData = DateTime.TryParseExact(text, "MM/dd/yyyy", 
          CultureInfo.InvariantCulture, 
          DateTimeStyles.None, 
          out "01/01/2013"); 
+0

Не могу заставить это работать, когда я использую DateTime.TryParseExact. Возвращаемое значение - bool, а не значение String, которое ожидается. В любом случае, мне действительно нужно передать «if (! ModelState.IsValid)» с нулевыми значениями в датах. Я пытался «установить» значения вручную, потому что не смог получить ModelView Pass «ModelState.isValid». Я действительно думаю, что это имеет какое-то отношение к «исправлению», которое я сделал по следующей ссылке http://stackoverflow.com/questions/11272851/format-datetime-in-asp-net-mvc- Это, вероятно, ошибка в формате dateformat от pt-BR до en-US от ModelView и просмотра. –

1

Ваша модель состояния не удается из-за аннотации GreaterThan данных на вашем втором обнуляемого значение DateTime. null не больше нуля, поэтому он не работает. Вам нужно будет либо изменить аннотацию данных GreaterThan, чтобы не сравнивать, если значения, если они являются нулевыми или удаляют эту аннотацию данных, и делают сравнение самостоятельно. Примером может служить:

if(model.CadastroInicialData.HasValue() && model.CadastroFinalData.HasValue() && model.CadastroInicialData.Value > model.CadastroFinalData.Value){ 
    ModelState.AddModelError("CadastroInicialData", "CadastroInicialData must be less than CadastroFinalData"); 
} 

if(!modelState.IsValid()){ 
    Produto_Repository.Index_Listar_Produtos Model_list = Produto_Repository.GetProdutoByAll(); 
    ViewModel.Index_List_Produto = Model_list.Index_List_Produto; 
    return View("Index", ViewModel); 
} 
Смежные вопросы