简体   繁体   English

ASP.NET自定义模型绑定:DateTime

[英]ASP.NET Custom Model Binding: DateTime

The problem 问题

At this point I have a problem where my Get action is trying to read a DateTime parameter in a diferent format that is sent. 此时,我有一个问题,其中我的Get操作试图读取发送的不同格式的DateTime参数。

While the DateTime sent has this format: 0:dd/MM/yyyy The Get Actions expects: 0:MM/dd/yyyy 虽然发送的DateTime具有以下格式: 0:dd/MM/yyyy Get Actions期望: 0:MM/dd/yyyy

The solution (maybe) 解决方法(也许)

In order to change what the Get action is expecting I'm using a Custom Model Binding. 为了更改Get操作所期望的,我使用了自定义模型绑定。

The GET Action GET动作

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

The ModelBinder class ModelBinder类

Now here are a few things that are missing and I don't know how to complete it properly: 现在这里缺少一些东西,我不知道如何正确完成它:

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

    }
}

I've several questions marked as comments in the code above since I'm just starting to understand Custom Model Binding. 由于我刚刚开始了解自定义模型绑定,因此我在上面的代码中将几个问题标记为注释。 Hope anyone can give me some advice. 希望任何人都能给我一些建议。

I'm following this article: 我正在关注这篇文章:

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

But it's from 2008!!! 但这是从2008年开始!!! , Although it seems valid since it's exactly the problem I'm having with my GET Action (diferent date formats) ,尽管它似乎是有效的,因为这正是我的GET Action(不同的日期格式)所遇到的问题

Update: aditional information 更新:附加信息

The parameter date is defined as: 参数date定义为:

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

and the URL build when calling that GET Action has this structure for the date parameter: 并在调用GET Action具有date参数的结构时构建URL:

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

You have several issues with your model binder implementation: 您的模型绑定程序实现存在几个问题:

  1. Do not hardcode parameter name ( date ). 不要硬编码参数名称( date )。 Use bindingContext.ModelName instead. 请改用bindingContext.ModelName
  2. You should handle situation if value was not actually provided. 如果未实际提供价值,则应处理情况。 You could check it by comparing result of IValueProvider.GetValue() with ValueProviderResult.None . 您可以通过将IValueProvider.GetValue()结果与ValueProviderResult.None进行比较来进行检查。

Here is sample DateTime model binder that accomplish what you need: 这是示例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);
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM