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

时间:2016-09-30 14:50:34

标签: c# asp.net-core-mvc model-binding custom-model-binder asp.net-core-webapi

我正在编写ASP.NET Core 1应用程序,它有一个Web API Controller,供应商将发布数据。

这是我将绑定传入数据的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,继续前进,然后返回 {{1>的每个属性} class
显然情况并非如此,我的自定义Lead永远不会被击中。

我说IModelBinder似乎是强制性的原因是我没有办法直接将IModelBinderProvider注册到MVC管道中;我 来注册IModelBinderProvider:

IModelBinder

如何让ASP.NET Core MVC将我的自定义public void ConfigureServices(IServiceCollection services) { // Add framework services. services.AddMvc(options => { options.ModelBinderProviders.Insert(0, new GermanDateTimeModelBinderProvider()); }); } 绑定器应用于DateTime类的Date属性? 有没有办法可以跳过整个Lead业务,只使用IModelBinderProvider

1 个答案:

答案 0 :(得分:1)

您是否将您的值发布为JSON? 如果是这样,我建议您使用JSON.NET注册自定义JsonConverter。 在转换器中,您将使用具有不同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);
}