【问题标题】:How do I migrate dynamic binding code in MVC from .NET Framework to .NET Core?如何将 MVC 中的动态绑定代码从 .NET Framework 迁移到 .NET Core?
【发布时间】:2019-06-10 20:31:51
【问题描述】:

我的任务是将 MVC 中的一些代码从 .NET Framework 转换为 .NET Core。该代码基于一个简单的模式将视图动态绑定到适当的模型。视图名称是页面中传输的第一个字段。例如,如果第一个数据字段是 PAGE1,则有一个名为 PAGE1Model 的对应模型。该代码使用 ModelBindingContext() 进行动态绑定。此代码在 .NET Framework 中完美运行,但在 .NET Core 中使用语法。

我尝试编写我认为在 .NET Core 中等效的内容。它编译但它不起作用。据我了解,在 .NET Core 和 Framework 中的表面绑定产生相同的结果,但在内部它们是不同的,我认为这就是导致问题的原因。由于我是 .NET Core 的新手,我花了 3 天时间搜索一些代码,这些代码会将模型动态分配给 Binder,但我可以找到的每个示例都会动态更改视图或模型中的某些内容,但假设视图和模型本身是固定。

这是在 .NET Framework 中工作的代码

private void BindModel(MapModel pModel)
    {
        Type ModelType = pModel.GetType();
        // bind model data
        var binder = Binders.GetBinder(ModelType);
        ModelBindingContext bindingContext = new ModelBindingContext()
        {
            ModelMetadata = 
              ModelMetadataProviders.Current.GetMetadataForType(() 
           => pModel, ModelType),
            ModelState = ModelState,
            ValueProvider = new FormValueProvider(this.ControllerContext)
        };
        binder.BindModel(ControllerContext, bindingContext);
    }

输入是地图的名称+“模型”,例如BindModel(Map1Model)

我对 .NET Core 的一次尝试是,它不起作用,是

public class ModelBinder : IModelBinder
{
    public ModelBinder(MapModel pModel, ControllerContext pContext)
    {
        model = pModel;
        context = pContext;
    }
    MapModel model;
    ControllerContext context;
    private readonly IModelBinder thisBinder;
    public Task BindModelAsync(ModelBindingContext bindingContext)
    {
        if (bindingContext == null)
        {
            throw new ArgumentNullException(nameof(bindingContext));
        }
        bindingContext.Model = model;
        bindingContext.ValueProvider = (IValueProvider) context;
        return Task.CompletedTask;
    }
}

新的电话是

ModelBinder BindModel = new ModelBinder(Model, this.ControllerContext);

我预计这将完成与 .NET Framework 代码相同的事情,但它没有做任何事情,因为 BindModelAsync 任务从未运行。

该应用程序是从大型机 COBOL 迁移到 C# .NET 的遗留应用程序,因此我受限于无法更改输入格式或视图名称和模型名称之间的对应关系。

【问题讨论】:

  • 动态绑定是什么意思?在 Core 中默认绑定是动态的。
  • Controller 中最常见的情况是在编译时指定 View 和 Model 的名称。我使用动态绑定来指示视图和模型是在运行时指定的,并且将从一个事务更改为另一个事务。

标签: c# asp.net-core


【解决方案1】:

接受的答案在现代 C# 语法中重写为非阻塞

public async Task<IActionResult> Action() {
    // ...
    if (ModelState.IsValid)
    {
        var result = await TryUpdateModelAsync(Model, Model.GetType(), "");
        if (!result)
           throw new Exception("TxServerController.TxMap: TryUpdateModelAsync failed");
    }
    ModelState.Clear();
}

【讨论】:

    【解决方案2】:

    为了其他有类似问题的人的利益,这是我想出的实际有效的代码:

    if (this.ModelState.IsValid)
                {
                    Task<bool> task = this.TryUpdateModelAsync(Model, Model.GetType(), "");
                    task.Wait();
                    if (!task.Result)
                        throw new Exception("TxServerController.TxMap: TryUpdateModelAsync failed");
                }
                this.ModelState.Clear();
    

    【讨论】:

    • 你之前用过await这个关键字吗?
    • 在这种情况下,等待是必要的关键字,因为在执行任何后续代码之前需要完成绑定。
    • 这就是 await 的作用。 await 等待而不阻塞线程。 Wait() 也等待但阻塞。 stackoverflow.com/questions/13140523/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-17
    • 1970-01-01
    • 2022-08-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多