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

时间:2017-11-23 06:33:29

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

问题

此时我遇到一个问题,我的Get操作尝试以不同的格式读取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?
        }

    }
}

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

我正在关注这篇文章:

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 Action时的URL构建具有date参数的结构:

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

1 个答案:

答案 0 :(得分:3)

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

  1. 不要硬编码参数名称(date)。请改用bindingContext.ModelName
  2. 如果实际没有提供价值,您应该处理情况。您可以通过将IValueProvider.GetValue()的结果与ValueProviderResult.None进行比较来检查。
  3. 以下是完成所需内容的示例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);
        }
    }