Net Core Web API如何以dd-MM-yyyy格式接受日期? [英] How to acccept date in dd-MM-yyyy format in net core web api?

查看:61
本文介绍了Net Core Web API如何以dd-MM-yyyy格式接受日期?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在我的Web API项目中使用的是net core 3.1.我创建了一个API,该API接受来自用户的日期.默认情况下,项目中接受 MM-dd-yyyy 格式.但是我想接受 dd-MM-yyyy 格式的日期,并相应地验证所有日期.

下面是我的api:

  [HttpGet]公共异步Task< IActionResult>获取(DateTime fromDate,DateTime toDate){返回Ok();} 

此外,我还有一些API,其中date参数作为JSON传递到请求主体中.我尝试了以下StackOverflow答案,但没有任何效果:

参考:

http://www.vickram.me/custom-datetime-model-binding-in-asp-net-core-web-api

更新:

您可能会看到可以将 dd-MM-yyyy 日期传递给操作,但是接收格式仍然与以前一样.这是设计使然,请参阅:

https://stackoverflow.com/a/58103218/11742476

The above solution worked when passing the date inside the request body but not when passing the date in the URL.

Is there any other way through which I can achieve this. ?

解决方案

You could custom model binder for the DateTime format like below:

1.DateTimeModelBinderProvider:

public class DateTimeModelBinderProvider : IModelBinderProvider
{
    public IModelBinder GetBinder(ModelBinderProviderContext context)
    {
        if (DateTimeModelBinder.SUPPORTED_TYPES.Contains(context.Metadata.ModelType))
        {
            return new BinderTypeModelBinder(typeof(DateTimeModelBinder));
        }

        return null;
    }
}

2.DateTimeModelBinder:

public class DateTimeModelBinder : IModelBinder
{
    public static readonly Type[] SUPPORTED_TYPES = new Type[] { typeof(DateTime), typeof(DateTime?) };

    public Task BindModelAsync(ModelBindingContext bindingContext)
    {
        if (bindingContext == null)
        {
            throw new ArgumentNullException(nameof(bindingContext));
        }

        if (!SUPPORTED_TYPES.Contains(bindingContext.ModelType))
        {
            return Task.CompletedTask;
        }

        var modelName = GetModelName(bindingContext);

        var valueProviderResult = bindingContext.ValueProvider.GetValue(modelName);
        if (valueProviderResult == ValueProviderResult.None)
        {
            return Task.CompletedTask;
        }

        bindingContext.ModelState.SetModelValue(modelName, valueProviderResult);

        var dateToParse = valueProviderResult.FirstValue;

        if (string.IsNullOrEmpty(dateToParse))
        {
            return Task.CompletedTask;
        }

        var dateTime = Helper.ParseDateTime(dateToParse);

        bindingContext.Result = ModelBindingResult.Success(dateTime);

        return Task.CompletedTask;
    }

    private string GetModelName(ModelBindingContext bindingContext)
    {
        if (!string.IsNullOrEmpty(bindingContext.BinderModelName))
        {
            return bindingContext.BinderModelName;
        }

        return bindingContext.ModelName;
    }
}


public class Helper
{
    public static DateTime? ParseDateTime(
        string dateToParse,
        string[] formats = null,
        IFormatProvider provider = null,
        DateTimeStyles styles = DateTimeStyles.None)
    {
        var CUSTOM_DATE_FORMATS = new string[]
            {    
            //"MM-dd-yyyy",
            "yyyy-MM-dd",
            "dd-MM-yyyy"
            };

        if (formats == null || !formats.Any())
        {
            formats = CUSTOM_DATE_FORMATS;
        }

        DateTime validDate;

        foreach (var format in formats)
        {
            if (format.EndsWith("Z"))
            {
                if (DateTime.TryParseExact(dateToParse, format,
                         provider,
                         DateTimeStyles.AssumeUniversal,
                         out validDate))
                {
                    return validDate;
                }
            }

            if (DateTime.TryParseExact(dateToParse, format,
                     provider, styles, out validDate))
            {
                return validDate;
            }
        }
        return null;
    }
}

3.Startup.cs:

services.AddControllers(option =>
{
     // add the custom binder at the top of the collection
     option.ModelBinderProviders.Insert(0, new DateTimeModelBinderProvider());
})

If you still want to display the dd-MM-yyyy format date,change your Startup.cs:

services.AddControllers(option =>
{
     option.ModelBinderProviders.Insert(0, new DateTimeModelBinderProvider());
}).AddJsonOptions(options =>
{
     options.JsonSerializerOptions.Converters.Add(new DateTimeConverter());
});

Result:

Reference:

http://www.vickram.me/custom-datetime-model-binding-in-asp-net-core-web-api

Update:

You could see that you can pass dd-MM-yyyy date to the action but the receive format is still as before.This is by design,refer to:

https://docs.microsoft.com/en-us/aspnet/core/mvc/models/model-binding?view=aspnetcore-3.1#globalization-behavior-of-model-binding-route-data-and-query-strings

这篇关于Net Core Web API如何以dd-MM-yyyy格式接受日期?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆