C#MVC 4 ViewModel不接受null DateTime

学习C#和mvc4在这里遇到了一些麻烦。

问题出现在我的应用程序的filter部分。 我有一个ViewModel,它抓取数据库的“Listar_Produtos”列表,以及一些搜索选项的字段。

我打算做的是让filter接受任何字段,即使它是空值。 因为我会根据这些参数制作filter。

我有一个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 Index_List_Produto { get; set; } [Display(Name = "Data de Cadastro Inicial")] [DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:dd/MM/yyyy}")] public Nullable 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 CadastroFinalData { get; set; } } } } 

我有以下观点:

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

在我的控制器中,我有:

 [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。

但是如果我在Fields中没有提供任何内容(在我的视图中都是Datefields),那么“if(!ModelState.IsValid)”将返回true并输入“if”,因为“CadastroInicialData”和“CadastroFinalData”都带有空值

期望的行为是ViewModel可以接受由“Nullable”或“DateTime?”授予的null值或空值。

我尝试将值插入可空日期字段,执行以下操作:

 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的日期时间,问题如下: 在asp.net mvc 4中格式化日期时间

当文本字段没有填充日期时,如何使ViewModel接受空值? 我在这里有点困惑。 我赞成任何帮助! 谢谢 !

您可以向Model类添加其他属性,然后使用它们来确定值是否为null。 并在您的视图中实现它们。 见下面的代码:

模型

 public class Index_Listar_Produtos { public List Index_List_Produto { get; set; } [Display(Name = "Data de Cadastro Inicial")] [DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:dd/MM/yyyy}")] public Nullable 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 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(); } } } 

视图

  @Html.LabelFor(Model => Model.GetStringTypeCadastroInicialData)
@Html.TextBoxFor(Model => Model.GetStringTypeCadastroInicialData) @Html.ValidationMessageFor(Model => Model.GetStringTypeCadastroInicialData) @Html.LabelFor(Model => Model.GetStringTypeCadastroFinalData)
@Html.TextBoxFor(Model => Model.GetStringTypeCadastroFinalData) @Html.ValidationMessageFor(Model => Model.GetStringTypeCadastroFinalData)

代替

 public Nullable CadastroInicialData { get; set; } 

尝试

 public DateTime? CadastroInicialData { get; set; } 

然后要查看它是否有值,你可以这样做:

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

由于第二个可以为空的DateTime值上的GreaterThan数据注释,您的模型状态失败。 null不大于null,因此失败。 您将需要修改GreaterThan数据注释,以便不比较值是否为null或删除该数据注释并自行进行比较。 一个例子可能是:

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

而不是使用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");