我正在将一个MVC5项目转换为核心。我目前有一个自定义模型绑定器,我将其用作我的nhibernate实体模型绑定器。我可以选择获取和绑定,方法是从数据库中获取实体,然后调用基本DefaultModelBinder将修改后的数据从请求绑定到实体中。
现在我正在尝试实现IModelBinder...我可以很好地获取实体。但是,当我不再需要调用基本DefaultModelBinder时,如何调用“默认模型绑定器”来绑定其余的表单数据呢?
提前感谢!
发布于 2020-01-11 02:12:27
你可以这样做:
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.AspNetCore.Mvc.ModelBinding.Binders;
using Microsoft.Extensions.DependencyInjection;
using Newtonsoft.Json;
namespace Media.Onsite.Api.Middleware.ModelBindings
{
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc(options =>
{
// add the custom binder at the top of the collection
options.ModelBinderProviders.Insert(0, new MyCustomModelBinderProvider());
});
}
}
public class MyCustomModelBinderProvider : IModelBinderProvider
{
public IModelBinder GetBinder(ModelBinderProviderContext context)
{
if (context.Metadata.ModelType == typeof(MyType))
{
return new BinderTypeModelBinder(typeof(MyCustomModelBinder));
}
return null;
}
}
public class MyCustomModelBinder : IModelBinder
{
public Task BindModelAsync(ModelBindingContext bindingContext)
{
if (bindingContext == null)
{
throw new ArgumentNullException(nameof(bindingContext));
}
if (bindingContext.ModelType != typeof(MyType))
{
return Task.CompletedTask;
}
string modelName = string.IsNullOrEmpty(bindingContext.BinderModelName)
? bindingContext.ModelName
: bindingContext.BinderModelName;
ValueProviderResult valueProviderResult = bindingContext.ValueProvider.GetValue(modelName);
if (valueProviderResult == ValueProviderResult.None)
{
return Task.CompletedTask;
}
bindingContext.ModelState.SetModelValue(modelName, valueProviderResult);
string valueToBind = valueProviderResult.FirstValue;
if (valueToBind == null /* or not valid somehow*/)
{
return Task.CompletedTask;
}
MyType value = ParseMyTypeFromJsonString(valueToBind);
bindingContext.Result = ModelBindingResult.Success(value);
return Task.CompletedTask;
}
private MyType ParseMyTypeFromJsonString(string valueToParse)
{
return new MyType
{
// Parse JSON from 'valueToParse' and apply your magic here
};
}
}
public class MyType
{
// Your props here
}
public class MyRequestType
{
[JsonConverter(typeof(UniversalDateTimeConverter))]
public MyType PropName { get; set; }
public string OtherProp { get; set; }
}
}发布于 2021-08-31 13:54:09
我也处于同样的境地。我需要从数据库实例化对象,然后让MVC/Core为我绑定所有属性。经过几个小时的谷歌搜索和“堆栈溢出”,这是我构建的:
public class MyBinder : ComplexTypeModelBinder
{
public SettingsBinder(IDictionary<ModelMetadata, IModelBinder> propertyBinders) : base(propertyBinders, new LoggerFactory()) { }
protected override object CreateModel(ModelBindingContext bindingContext)
{
return Get_Object_From_Database(); //custom creation logic
}
}
public class MyBinderProvider : IModelBinderProvider
{
public IModelBinder GetBinder(ModelBinderProviderContext context)
{
//make sure I use it with my type only
if (context.Metadata.ModelType == typeof(My_Object))
{
//get property binders for all the stuff
var propertyBinders = context.Metadata.Properties.ToDictionary(p => p, p => context.CreateBinder(p));
return new MyBinder(propertyBinders);
}
return null;
}
}
//startup.cs
services.AddMvc(option =>
{
option.ModelBinderProviders.Insert(0, new MyBinderProvider());
});ComplexTypeModelBinder被标记为过时,但微软团队在github上表示,这意味着该类型不应由微软内部使用,但它将继续存在。
使用.NET 5测试成功
https://stackoverflow.com/questions/50893324
复制相似问题