在 asp.net 核心中替代 HttpConfigurationExtensions.BindParameter

Posted

技术标签:

【中文标题】在 asp.net 核心中替代 HttpConfigurationExtensions.BindParameter【英文标题】:Alternative to HttpConfigurationExtensions.BindParameter in asp.net core 【发布时间】:2019-10-11 14:29:55 【问题描述】:

我正在 ASP .NET 核心中寻找 .NET 框架 MVC 中 HttpConfigurationExtensions.BindParameter 方法的替代方法。

我正在尝试为我拥有的枚举创建模型绑定器。 我希望有与默认行为不同的行为。

在 .net 框架中我会这样做。

config.BindParameter(typeof(MyEnum), new MyEnumBinder());

然后我可以在我的请求对象类中使用该枚举。像这样。

public class MyRequestObject 

    public string ExampleProp  get; set; 
    public MyEnum ExampleEnum  get; set; 

如何在 ASP .Net 核心中做同样的事情?

我看过这个https://docs.microsoft.com/en-us/aspnet/core/mvc/advanced/custom-model-binding?view=aspnetcore-2.2 并尝试实现它。不幸的是,如果我使用ModelBinderProvider,它只会触发MyRequestObject 类型而不是MyEnum,所以我不能只针对MyEnum 类型。

有什么想法吗?

【问题讨论】:

【参考方案1】:

为什么不使用 JsonConverter 代替模型绑定器?

看看这个:

public enum ElapsedTime
    
        Unknown = 1,
        SomeSeconds = 2,
        LessThanTenMinutes = 3,
        LessThanThirtyMinutes = 4,
        LessThanAnHour = 5,
        MoreThanAnHour = 6
    

JsonConverter 实现:

public class ElapsedTimeJsonConverter : JsonConverter<ElapsedTime>
    
        public override ElapsedTime ReadJson(JsonReader reader, Type objectType, ElapsedTime existingValue, bool hasExistingValue, JsonSerializer serializer)
        
            if (!DateTime.TryParse(reader.ReadAsString(), out var date))
                return ElapsedTime.Unknown;

            var elapsedTime = default(ElapsedTime);
            var timeDifference = date.Subtract(DateTime.Now).TotalMinutes;

            if (timeDifference < 1)
            
                elapsedTime = ElapsedTime.SomeSeconds;
            
            else if (timeDifference >= 1 && timeDifference < 10)
            
                elapsedTime = ElapsedTime.LessThanTenMinutes;
            
            else if (timeDifference >= 10 && timeDifference < 30)
            
                elapsedTime = ElapsedTime.LessThanThirtyMinutes;
            
            else if (timeDifference >= 30 && timeDifference < 60)
            
                elapsedTime = ElapsedTime.LessThanAnHour;
            
            else if (timeDifference >= 60)
            
                elapsedTime = ElapsedTime.MoreThanAnHour;
            

            return elapsedTime;

        

        public override void WriteJson(JsonWriter writer, ElapsedTime value, JsonSerializer serializer)
        
            throw new NotImplementedException();
        
    

和启动:

public void ConfigureServices(IServiceCollection services)
        

            //Only for preventing validation errors
            services.AddSingleton<IObjectModelValidator>(new NullObjectModelValidator());
            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
                .AddJsonOptions(options => options.SerializerSettings.Converters.Add(new ElapsedTimeJsonConverter()));
        

【讨论】:

这就是我目前实现它的方式。不幸的是,它需要具有“未知”或可为空的状态。我认为必须在我的控制器验证中验证枚举是否具有“正确”值。使用模型绑定器,我可以返回一个很好的消息,说它无效,而我的控制器中没有逻辑。

以上是关于在 asp.net 核心中替代 HttpConfigurationExtensions.BindParameter的主要内容,如果未能解决你的问题,请参考以下文章

ASP.NET 4.5 或替代框架中的 OpenIdDict?

ASP.NET Core 中 Server.Transfer 的替代方案

.NET Core(或 ASP.NET 5)中是不是有 MEF 的替代品

什么是 ASP.NET / PHP 的主流 Java 替代品

ASP.NET MVC 中 Controller.ReadFromRequest 的替代品是啥?

ASP.NET MVC 5 实体框架替代方案或在运行时指定架构的能力?