使用阿拉伯语日期时间处理请求正文

时间:2017-11-24 23:02:01

标签: c# asp.net api asp.net-core

我有ASP.NET核心API,模型如下

public class UserDetails
 {
    public string name{ get; set; };
    public DateTime SyncTime{ get; set; };
 }

有时我的请求正文中包含SyncTime的阿拉伯数字,如 2017-11-05 09:08:01 有没有办法正确处理这种格式和处理请求?

2 个答案:

答案 0 :(得分:1)

如果您有选择,通常最容易指示客户端使用标准DateTime {{3}将所有DateTime个对象作为unix毫秒发送,或作为"O"发送}。由于您正在编写API,因此您可以确定哪些是有效输入,并且可以拒绝任何非此格式的内容。

我知道你并不总是那么奢侈,在这种情况下你可以为DateTime编写一个使用特定文化的自定义模型绑定器:

public class ArabicDateTimeBinder: IModelBinder
{
    public Task BindModelAsync(ModelBindingContext bindingContext)
    {
        var modelName = bindingContext.BinderModelName;
        var valueProviderResult = bindingContext.ValueProvider.GetValue(modelName);

        if (valueProviderResult == ValueProviderResult.None)
            return Task.CompletedTask;

        bindingContext.ModelState.SetModelValue(modelName, valueProviderResult);

        var value = valueProviderResult.FirstValue;

        if (string.IsNullOrEmpty(value))
            return Task.CompletedTask;

        DateTime dateTime;
        // I'm unsure whether this will handle the arabic digits correctly or not, so I have also included the suggested approach by g.Irani as a fallback
        if (DateTime.TryParse(value, new CultureInfo("ar"), DateTimeStyles.None, out dateTime))
        {
            bindingContext.Result = ModelResult.Success(dateTime);
            return Task.CompletedTask;
        }

        // As per g.Irani's suggestion:
        value = value.Replace('\u06f0', '0')
                .Replace('\u06f1', '1')
                .Replace('\u06f2', '2')
                .Replace('\u06f3', '3')
                .Replace('\u06f4', '4')
                .Replace('\u06f5', '5')
                .Replace('\u06f6', '6')
                .Replace('\u06f7', '7')
                .Replace('\u06f8', '8')
                .Replace('\u06f9', '9');

        if (DateTime.TryParse(value, out dateTime))
        {
            bindingContext.Result = ModelResult.Success(dateTime);
            return Task.CompletedTask;
        }

        bindingContext.ModelState.TryAddModelError(bindingContext.ModelName, "DateTime was not in the expected format");
        return Task.CompletedTask;
    }
}

然后你需要告诉ASP.Net使用这个绑定器。您可以直接在类上使用注释来执行此操作,这是最简单的方法:

public class UserDetails
{
    public string name{ get; set; };
    [ModelBinder(BinderType = typeof(ArabicDateTimeBinder))]
    public DateTime SyncTime{ get; set; };
}

或者,您可以创建并注册IModelBinderProvider。注册此提供程序时,它将应用于包含DateTime成员的所有模型。有关自定义模型绑定器的更多信息,请round-trip format specifier

public class ArabicDateTimeBinderProvider : IModelBinderProvider
{
    public IModelBinder GetBinder(ModelBinderProviderContext context)
    {
        if (context == null)
            throw new ArgumentNullException(nameof(context));

        if (context.Metadata.ModelType == typeof(DateTime))
            return new BinderTypeModelBinder(typeof(ArabicDateTimeBinder));

        return null;
    }
}

使用ConfigureServices方法注册提供商:

public void ConfigureServices(IServiceCollection services)
{
    // All your other service configuration stuff
    services.AddMvc(options =>
    {
        // add custom binder to beginning of collection
        options.ModelBinderProviders.Insert(0, new ArabicDateTimeBinderProvider());
    });
}

免责声明:我没有运行上面的代码,我只是写下我记得的内容。它应该可以工作,但可能需要修改一两件事。

答案 1 :(得分:-1)

        CultureInfo culture = new CultureInfo("ar");
        string datepattern = culture.DateTimeFormat.LongDatePattern;
        DateTimeFormatInfo datetimeFormatInfo = new DateTimeFormatInfo();
        datetimeFormatInfo.LongDatePattern = "yyyy-MM-dd";
        culture.DateTimeFormat = datetimeFormatInfo;
        Thread.CurrentThread.CurrentCulture = culture;
        DateTime dateArabic = DateTime.Now; //SyncTime
        //---
        DateTime SyncTime;
        if(DateTime.TryParse(" ٢٠١٧-١١-٠٥ ٠٩:٠٨:٠١ ", new CultureInfo("ar")) == null){//Error};