I’ve been tasked with converting some code we have in MVC from .NET Framework to .NET Core. The code dynamically binds a View to the appropriate Model based on a simple pattern. The View name is the first field in the page that is transmitted. For example, if the first data field is PAGE1 then there is a corresponding Model named PAGE1Model. The code does the dynamic binding by using ModelBindingContext(). This code works perfectly in .NET Framework but syntaxes in .NET Core.
I tried writing what I thought would be the equivalent in .NET Core. It compiles but it doesn't work. As I understand it, on the surface binding in .NET Core and Framework produce the same results but inside they’re different and I think that’s what’s causing the problem. Since I’m new to .NET Core I’ve spent 3 days searching for some code that will dynamically assign a Model to a Binder but every example I can find dynamically changes something within the View or Model but assumes the View and Model themselves are fixed.
This is the code that works in .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);
}
The input is the name of the Map + "Model" e.g. BindModel(Map1Model)
My one attempt at .NET Core, which doesn't work, is
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;
}
}
and the new call is
ModelBinder BindModel = new ModelBinder(Model, this.ControllerContext);
I expected this would accomplish the same thing as the .NET Framework code but it isn't doing anything because the BindModelAsync task is never being run.
The application is a legacy application moved to C# .NET from mainframe COBOL so I’m constrained in that I can’t change the input format or the correspondence between View name and Model name.