Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#MVC 4 ViewModel不接受空DateTime_C#_Asp.net Mvc_Asp.net Mvc 4_Datetime_Mvvm - Fatal编程技术网

C#MVC 4 ViewModel不接受空DateTime

C#MVC 4 ViewModel不接受空DateTime,c#,asp.net-mvc,asp.net-mvc-4,datetime,mvvm,C#,Asp.net Mvc,Asp.net Mvc 4,Datetime,Mvvm,我在这里学习C#和mvc4有点麻烦 问题发生在我的应用程序的过滤器部分。 我有一个ViewModel,它获取数据库的“Listar_Produtos”列表,以及一些用于搜索选项的字段 我打算做的是让过滤器接受任何字段,即使它是空值。因为我将根据这些参数生成过滤器 我有一个Viewmodel: using Foolproof; using System; using System.Collections.Generic; using System.ComponentModel; using Sys

我在这里学习C#和mvc4有点麻烦

问题发生在我的应用程序的过滤器部分。 我有一个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; }
        }
    }
}
其中“Produto_Repository.GetProdutoByAll();”再次返回“Produto”列表

如果我在表单中提供日期,代码运行良好。日期采用“pt BR”格式:2013年3月23日

但是如果我在字段中没有提供任何内容(视图中的两个日期字段),那么“if(!ModelState.IsValid)”将返回true并输入“if”,因为“cadastroinicaldata”和“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的日期时间,以解决以下问题:

当文本字段未填充日期时,如何使ViewModel接受空值? 我有点困惑。我感谢你的帮助!谢谢

而不是

public Nullable<DateTime> CadastroInicialData { get; set; }
然后,要查看它是否有值,可以执行以下操作:

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

使用DateTime.TryParseExact代替Convert.ToDateTime,您可以指定格式和区域性。下面的代码应该可以工作并修复错误:

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

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

型号

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

}
public class Index\u Listar\u Produtos
{
公共列表索引\u List\u Produto{get;set;}
[显示(Name=“地籍数据”)]
[DisplayFormat(ApplyFormatInEditMode=true,DataFormatString=“{0:dd/MM/yyyy}”)]
公共可为空的CADASTROINICALDATA{get;set;}
[显示(Name=“最终地籍数据”)]
[DisplayFormat(ApplyFormatInEditMode=true,DataFormatString=“{0:dd/MM/yyyy}”)]
[GreaterThanOrEqualTo(“地籍临时数据”,ErrorMessage=“\“数据临时性”,deve ser maior que\“数据最终版”)]
公共可为空的CadastroFinalData{get;set;}
公共字符串GetStringTypeCadastroInialData
{
获取{return CadastroInicialData!=null?CadastroInicialData.Value.ToSortDateString():DateTime.MinValue.ToSortDateString()(或空字符串);}
}
公共字符串GetStringTypeCadastroFinalData
{
获取{return cadastroinicaldata!=null?CadastroFinalData.Value.ToSortDateString():DateTime.Now.ToSortDateString();}
}
}
查看

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

@Html.LabelFor(Model=>Model.getStringTypeCadastroInialData)
@Html.TextBoxFor(Model=>Model.getStringTypeCadastroInialData) @Html.ValidationMessageFor(Model=>Model.getStringTypeCadastroInialData) @Html.LabelFor(Model=>Model.GetStringTypeCadastroFinalData)
@Html.TextBoxFor(Model=>Model.GetStringTypeCadastroFinalData) @Html.ValidationMessageFor(Model=>Model.GetStringTypeCadastroFinalData)
您的模型状态失败,因为第二个可为空的日期时间值上的
数据注释大于
。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);
}

这根本没用!约会时间?等于Nullable,我使用了这两个sintax,没有任何进步。这并不能解决我在Controller中通过ModelView传递可空日期的问题=当我使用DateTime.TryParseExact时,无法实现此功能。返回值是bool,而不是预期的字符串值。无论如何,我真正需要的是能够将带有空值的“if(!ModelState.IsValid)”传递给日期。我试图手动“设置”这些值,因为我无法让ModelView传递“ModelState.isValid”。我真的认为这与我在以下链接中所做的“修复”有关。这可能是从ModelView和view从pt BR到en US的日期格式转换错误。这是您的数据注释,请查看我的回答以了解原因。嗨@Tommy,数据注释的帮助者是“GreaterThanOrEqualTo”而不是“GreaterThan”。如果datetime都为空,则验证将成功…您是否100%同意?模型状态验证的错误是什么?我相信问题来自“ApplyFormatInEditMode=true”。我发布了一个答案,让你解决这个问题。如果你真的想修复它,看看这个链接,它可能会帮助你。林,谢谢你的回答。你的代码几乎节省了我的时间,唯一的“错误”是当我进入页面时,TextBoxFor被“设置”为默认值(因为此时该值为空)。文本框是搜索间隔的输入,无法开始填充。只有在控制器中,如果可以转换空值,那就太棒了。@Marcossantii,我认为如果在您可以使用“”而不是使用“”01/01/2013时,该值为空。此外,您不需要在TextBoxFor中使用“{0:dd/MM/yyyy}”日期时间格式化程序。让我更新这个。Lin,刚刚注意到这是错误的。“获取”{return CadastroInicialData!=null?CadastroFinalData.Value.ToSortDateString():“;}”将永远不会被触动。因为视图将尝试设置“GetStringTypeCadastroInicialData”,并且用户尝试搜索任何内容时不会更改CadastroFinalData=(@MarcosSantini,我对你的情况不是很清楚,但从你所说的来看,你似乎不能
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>
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);
}