I'm in a bit of trouble here learning C# and mvc4.
The Problem occurs in the Filter part of my application. I have an ViewModel that grabs the list of "Listar_Produtos" of the database, and some fields for searching options.
What I intend to do is make the filter accept any field, even if it's null values. Because i'll make the filter based on these paramters.
I Have an 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; }
}
}
}
And I have the following View:
<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>
In my Controller I have:
[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);
}
}
Where "Produto_Repository.GetProdutoByAll();" returns the list of "Produtos" again.
The code works fine and well if I provide dates in the form. The dates are in "pt-BR" format: 23/03/2013.
But if I provide nothing in the Fields (both Datefields in my View), than the "if(!ModelState.IsValid)" returns true and enters the "if", because both "CadastroInicialData" and "CadastroFinalData" comes with null values
The desired behavior is that the ViewModel could accept null or empty values that are granted by "Nullable" or "DateTime?".
I Tryed to insert values to the nullable date fields doing the following:
if (ViewModel.CadastroInicialData == null)
ViewModel.CadastroInicialData = Convert.ToDateTime("01/01/2013");
if (ViewModel.CadastroFinalData == null)
ViewModel.CadastroFinalData = Convert.ToDateTime("01/01/2013");
But now the ViewModel returns the following error: "is an invalid date format"
One note is that i'm using the following 'solution' for converting datetimes for pt-BR dateformat on the following question: Format datetime in asp.net mvc 4
How I make the ViewModel accept null values when the text fields are not filled with dates? I'm kinda confused here. I apreciate any help ! Thanks !
Instead of using Convert.ToDateTime use DateTime.TryParseExact, and you can specify format and culture. The below code should work and fix the errors:
Instead of
try
and then to see if it has a value, you can do:
Your model state is failing because of the
GreaterThan
data annotation on your second nullable DateTime value. null is not greater than null, so it is failing. You will either need to modify theGreaterThan
data annotation to not compare if the values if they are null or remove that data annotation and do the comparison yourself. An example could be:You can add another properties to your Model class, then use them to determine if the value is null or not. Also implement them in your view. See below code:
Model
View