警告 CS0618:'ComplexTypeModelBinder' 已过时

Warning CS0618: 'ComplexTypeModelBinder' is obsolete

在 .NET Core 3 中,我扩展了 ComplexTypeModelBinder class 来为特定的 class.

创建自定义模型绑定器

主要目标是通过 CreateModel 方法覆盖模型实例的创建。

public MyModelBinder: ComplexTypeModelBinder
{
    // Constructor here...
    
    protected override object CreateModel(ModelBindingContext bindingContext)
    {
        // Create model instance based on custom condition.
    }

}

升级到 .NET 5 后,我收到编译警告,要求将 ComplexTypeModelBinder 替换为 ComplexObjectModelBinder:

warning CS0618: 'ComplexTypeModelBinder' is obsolete: 'This type is obsolete and will be removed in a future version. Use ComplexObjectModelBinder instead.'

问题是 ComplexObjectModelBinder 被密封 class 并且 CreateModel 方法是 internal,所以 subclass 方法不能再工作了。

我确定的解决方案是创建 class MyModelBinder,它实现 IModelBinder 接口并作为 ComplexObjectModelBinder 的包装器。 ComplexObjectModelBinder 作为构造函数参数传入 MyModelBinder

MyModelBinderProviderComplexObjectModelProvider 使用相同的方法。

稍后,不再覆盖 ComplexObjectModelBinderCreateMethod,这在 .NET 5 中是不可能的,只需在 [=] 的包装器方法 BindAsyncModel 中分配 bindingContext.Model 12=],然后将 bindingContext 传递给 ComplexObjectModelBinderBindAsyncModel。这将使 ComplexObjectModelBinder 使用传入的模型,而不是创建默认的新实例。

public class MyModelBinder: IModelBinder
{
    private readonly ComplexObjectModelBinder _binder;
    public MyModelBinder(ComplexObjectModelBinder binder)
    {
        _binder = binder;
    }

    public Task BindModelAsync(ModelBindingContext bindingContext)
    {
        MyModel myModel = // custom instantiation logic here
        bindingContext.Model = myModel;
        return _binder.BindModelAsync(bindingContext);
    }
}

对于自定义模型绑定提供者的注册,首先我们找到现有的,自动注册的ComplexObjectBinderProvider,在MyModelBinderProvider的构造函数中使用它,然后在[前面插入MyModelBinderProvider =28=].

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllersWithViews(options => {
        // more configurations here...

        var bindingProvider = options.ModelBinderProviders.First(provider =>
            provider is ComplexObjectModelBinderProvider) as ComplexObjectModelBinderProvider;

        var indexOf = options.ModelBinderProviders.IndexOf(bindingProvider);

        options.ModelBinderProviders.Insert(indexOf, new MyModelBinderProvider(bindingProvider));
    }
}