【问题标题】:ASP.NET CORE How to Validate a Not Required Date?ASP.NET CORE 如何验证不需要的日期?
【发布时间】:2021-04-02 15:20:07
【问题描述】:

我得到一个 ModelState.IsValid,其日期类似于 2021 年 4 月 31 日(4 月只有 30 天),然后是我的 Convert.ToDateTime(form["StatusRangeFrom"]);抛出错误。

我需要一个空日期或有效日期。如何检查日期是否无效并将 ModelState 设置为无效,并返回带有正确的无效日期消息的视图?

型号:

    [Display(Name ="Date From")]
    [DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:MM/dd/yyyy}")]
    public Nullable<System.DateTime> StatusRangeFrom { get; set; }

控制器:

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Update(IFormCollection form)
 {
 UserPreferences userPreferences = await _conn.UserPreferences.FirstOrDefaultAsync(c => c.AccessID == Convert.ToInt32(form["AccessID"]));

  if (ModelState.IsValid)
   {
       if (form["StatusRangeFrom"].ToString() != "")
       {
           userPreferences.StatusRangeFrom = Convert.ToDateTime(form["StatusRangeFrom"]); // throws error on bad date
       }
       else
       {
           userPreferences.StatusRangeFrom = null;
    }
    
    
    await _conn.SaveChangesAsync();

查看:

            <div class="form-group">
                <label asp-for="StatusRangeFrom" class="control-label"></label>
                <input type="date" asp-for="StatusRangeFrom" class="form-control" />
                <span asp-validation-for="StatusRangeFrom" class="text-danger"></span>
            </div>

【问题讨论】:

  • 嗨,我试过你的代码,它工作正常。它不允许我到达显示无效日期错误的控制器。你能分享你的整个视图代码吗?
  • 错误是:Convert.ToDateTime(form["StatusRangeFrom"]); 2021 年 4 月 31 日这样的糟糕日期,因为 4 月只有 30 天。
  • 嗨@MatthewCox,回复是否解决了问题或者这个帖子有什么更新?如果答案解决了问题,请接受 - 请参阅What should I do when someone answers my question。如果它不起作用,您还可以创建自定义验证属性来验证数据,请参阅:Custom Model ValidationCustom attributes

标签: asp.net asp.net-mvc asp.net-core asp.net-core-3.1


【解决方案1】:

根据您的代码,我创建了一个示例,似乎在客户端,它会验证输入的日期是否有效,如果日期无效,它将阻止提交表单到操作,检查this screenshot.

然后是StatusViewModel.cs:

public class StatusViewModel
{
    public string Name { get; set; }

    [Display(Name = "Date From")]
    [DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:MM/dd/yyyy}")]
    public Nullable<System.DateTime> StatusRangeFrom { get; set; }
}

Create.cshtml:

@model WebApplication6.Data.StatusViewModel 
<div class="row">
    <div class="col-md-4">
        <form asp-action="Create">
            <div asp-validation-summary="ModelOnly" class="text-danger"></div>
            <div class="form-group">
                <label asp-for="Name" class="control-label"></label>
                <input asp-for="Name" class="form-control" />
                <span asp-validation-for="Name" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="StatusRangeFrom" class="control-label"></label>
                <input asp-for="StatusRangeFrom" class="form-control" />
                <span asp-validation-for="StatusRangeFrom" class="text-danger"></span>
            </div>
            <div class="form-group">
                <input type="submit" value="Create" class="btn btn-primary" />
            </div>
        </form>
    </div>
</div>

如果您禁用客户端验证或不使用提交表单方法提交表单。根据您的代码,因为您通过IFormCollection 获取输入的值。如果是这种情况,您可以尝试使用DateTime.TryParse() 方法验证日期。示例代码如下:

    [HttpPost]
    //[ValidateAntiForgeryToken]
    public async Task<IActionResult> Create(IFormCollection form)
    {
        StatusViewModel model = new StatusViewModel();
        model.Name = form["Name"];
        DateTime date;
        //check whether the date string is a valid date.
        if (DateTime.TryParse(form["StatusRangeFrom"], out date))
        {
            model.StatusRangeFrom = date;
        }
        else
        {
            //add the model error.
            ModelState.AddModelError("StatusRangeFrom", $"{form["StatusRangeFrom"]} is not an valid date!");
        }
        if (ModelState.IsValid)
        {
            //do something
        }

        return View();
    }

邮递员测试结果如下:

此外,在服务器端,有一个TryValidateModel() 方法,它可以用来手动重复验证模型,但在您的场景中,由于您需要将日期字符串转换为日期时间,所以我认为我们可以直接使用DateTime.TryParse()方法。有关使用TryValidateModel 方法的更多详细信息,请参阅this article

【讨论】:

  • 我必须在 if 中使用 DateTime.TryParseExact 函数才能使用 Convert.ToDateTime
【解决方案2】:

为了清楚起见,这是有效的:

if (form["StatusRangeFrom"].ToString() != "")
 {
   string format = "MM/dd/yyyy";
   DateTime dateFromTime;
   if (DateTime.TryParseExact(form["StatusRangeFrom"].ToString(), format, CultureInfo.InvariantCulture, DateTimeStyles.None, out dateFromTime))
     {
         userPreferences.StatusRangeTo = Convert.ToDateTime(form["StatusRangeFrom"]);  // now this doesn't error cause it doesn't get called with a bad date.
     }
   else
     {
         ModelState.AddModelError("StatusRangeFrom", "Must be a valid Date.");
     }
  }

知律让我非常接近!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-31
    • 2010-09-29
    • 1970-01-01
    • 2018-09-27
    • 1970-01-01
    • 2021-10-27
    相关资源
    最近更新 更多