我有ASP.NET核心API,模型如下
public class UserDetails
{
public string name{ get; set; };
public DateTime SyncTime{ get; set; };
}
有时我的请求正文中包含SyncTime
的阿拉伯数字,如 2017-11-05 09:08:01
有没有办法正确处理这种格式和处理请求?
答案 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};