【问题标题】:ASP.NET Custom Model Binding: DateTimeASP.NET 自定义模型绑定:DateTime
【发布时间】:2018-05-07 00:53:04
【问题描述】:

问题

此时我遇到了一个问题,我的 Get 操作正在尝试以不同格式读取发送的 DateTime 参数。

虽然发送的 DateTime 具有以下格式:0:dd/MM/yyyy Get Actions 期望:0:MM/dd/yyyy

解决方案(也许)

为了更改 Get 操作所期望的内容,我使用了自定义模型绑定。

GET 操作

    public async Task<IActionResult> Details(int? id, [ModelBinder(typeof(PModelBinder))]DateTime date)

ModelBinder 类

现在这里缺少一些东西,我不知道如何正确完成它:

public class PModelBinder : IModelBinder
{
    public Task BindModelAsync(ModelBindingContext bindingContext)
    {
        string theDate = bindingContext.HttpContext.Request.QueryString["date"]; 
        //What should I write inside the []? 
        //I've tried QueryString["date"] which is the name of the parameter but it says is wrong
        DateTime dt = new DateTime();
        bool success = DateTime.TryParse(date); //Should I apply ParseExact? How should I do it?
        if (success)
        {
            return new //what should I be returning here? dt?
        }

    }
}

由于我刚刚开始了解自定义模型绑定,因此我在上面的代码中将几个问题标记为 cmets。希望有人能给我一些建议。

我正在关注这篇文章:

https://weblogs.asp.net/melvynharbour/mvc-modelbinder-and-localization

但它来自 2008 年!!!,虽然这似乎是有效的,因为这正是我的 GET 操作遇到的问题(不同的日期格式)

更新:附加信息

参数日期定义为:

    [DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}", ApplyFormatInEditMode = true)]
    public DateTime FechaLInicioLiq { get; set; }

调用 GET 操作时构建的 URL 具有日期参数的这种结构:

date=10%2F11%2F2017%200%3A00%3A00

【问题讨论】:

  • Alberto 你需要 DateTime "0:MM/dd/yyyy" 到 "0:dd/MM/yyyy" 。我说对了吗……
  • @VIGNESHARUNACHALAM 使用以下格式发送日期时间:0:dd/MM/yyyy,但 GET 操作正在尝试读取参数,就好像它的格式是 0:MM/dd/yyyy,因此产生错误。所以我需要 GET 操作开始接受 0:dd/MM/yyyy 格式。
  • 建议您查看this article 中的代码以获取 core-mvc

标签: c# datetime asp.net-core-mvc


【解决方案1】:

您的模型绑定器实现存在几个问题:

  1. 不要硬编码参数名称 (date)。请改用bindingContext.ModelName。
  2. 如果实际没有提供值,您应该处理这种情况。您可以通过比较IValueProvider.GetValue() 和ValueProviderResult.None 的结果来检查它。

这是完成您需要的示例 DateTime 模型绑定器:

public class DateTimeModelBinder : IModelBinder
{
    private readonly IModelBinder baseBinder = new SimpleTypeModelBinder(typeof(DateTime));

    public Task BindModelAsync(ModelBindingContext bindingContext)
    {
        var valueProviderResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
        if (valueProviderResult != ValueProviderResult.None)
        {
            bindingContext.ModelState.SetModelValue(bindingContext.ModelName, valueProviderResult);

            var valueAsString = valueProviderResult.FirstValue;

            //  valueAsString will have a string value of your date, e.g. '31/12/2017'
            var dateTime = DateTime.ParseExact(valueAsString, "dd/MM/yyyy", CultureInfo.InvariantCulture);
            bindingContext.Result = ModelBindingResult.Success(dateTime);

            return Task.CompletedTask;
        }

        return baseBinder.BindModelAsync(bindingContext);
    }
}

【讨论】:

  • 感谢您的回复。我正在尝试实现它,但我收到一个错误,声称此行的结果: bindingContext.ModelState.SetModelValue(bindingContext.ModelName, valueProvideResult);一旦传递给 ParseExact 函数,该字符串就不会被识别为有效的 DateTime。我正在尝试在该行上对其进行调试以查看该值,但它会跳过该行并在我看到它之前抛出错误。
  • i.imgur.com/otBzAWe.png 它表示 SetModelValue 的结果,一旦为 PArseExact 函数评估,不被视为有效的 DateTime 格式):
  • 只要您的日期字符串还包含时间部分 (0:00:00),您应该为 ParseExact() 使用以下格式: DateTime.ParseExact(valueAsString, "dd/MM/yyyy h:m :s", CultureInfo.InvariantCulture)
  • 非常感谢!我正在尝试使用 0:dd/MM/yyyy 但还不够好。如果没有你的帮助,我想我不会处理这个问题!再次感谢!
  • 工作示例,但我建议可为空的 DateTime 如果未绑定则返回 null
猜你喜欢
  • 1970-01-01
  • 2017-02-09
  • 2011-01-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-14
  • 2011-04-27
相关资源
最近更新 更多