自定义DateTime模型绑定器.. NET Core 1 (RTM)

本文关键字:RTM Core NET DateTime 模型 绑定 自定义 | 更新日期: 2023-09-27 18:09:45

我在写ASP。. NET Core 1应用程序,它有一个Web API控制器,供应商可以在其中发布数据。

这是Model类的简化版本,我将把传入的数据绑定到它上面:

public class Lead
{
    public int SupplierId { get; set; }
    public DateTime Date { get; set; }
}

问题是日期将以德语格式发布,例如,30.09.2016。我不想将应用程序的全局文化设置为de-DE,因为a)我不是德国人,b)应用程序的其余部分将使用ISO日期。

我已经设置了写一个自定义的IModelBinder和,因为它显然是必须在ASP。. NET Core MVC和IModelBinderProvider .

这是我对IModelBinderProvider的实现:

public class GermanDateTimeModelBinderProvider : IModelBinderProvider
{
    public IModelBinder GetBinder(ModelBinderProviderContext context)
    {
        if (context == null)
            throw new ArgumentNullException(nameof(context));
        if (!context.Metadata.IsComplexType && 
                context.Metadata.ModelType == typeof(DateTime))
            return new GermanDateTimeBinder();
        return null;
    }
}

问题是我的IModelBinderProvider只被Lead类击中,即context.Metadata.ModelType == typeof(Lead)

我希望模型绑定器看到我们不是在处理DateTime,继续,然后返回 Lead的每个属性。
这显然不是这种情况,我的自定义IModelBinder从未被击中。

我说IModelBinderProvider似乎是强制性的原因是我没有找到直接注册IModelBinder到MVC管道的方法;我注册一个IModelBinderProvider代替:

public void ConfigureServices(IServiceCollection services)
{
    // Add framework services.
    services.AddMvc(options =>
    {
        options.ModelBinderProviders.Insert(0, new GermanDateTimeModelBinderProvider());
    });
}

我怎样才能得到ASP。. NET Core MVC应用我的自定义DateTime绑定到Lead类的Date属性?有没有一种方法可以跳过整个IModelBinderProvider业务,只使用IModelBinder ?

自定义DateTime模型绑定器.. NET Core 1 (RTM)

您是否将您的值作为JSON发布?如果是这样,我建议您注册一个自定义JsonConverter与JSON.NET。在转换器中,您将使用具有不同DateFormatString的JsonSerializer,在本例中是德语日期格式。所有其他JsonSerializer不受此影响。

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services
        .AddMvc()
        .AddJsonOptions(option =>
        {
            option.SerializerSettings.Converters.Add(new LeadConverter());
        });
    }
    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
        loggerFactory.AddDebug();
        app.UseMvcWithDefaultRoute();
    }
}
public class LeadConverter : JsonConverter
{
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new System.NotImplementedException();
    }
    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        var jsonSerializer = new JsonSerializer
        {
            DateFormatString = "dd.MM.yyyy"
        };
        return jsonSerializer.Deserialize<Lead>(reader);
    }
    public override bool CanConvert(Type objectType) => objectType == typeof(Lead);
}