水此篇博客,依旧是来自群里的讨论,最后说到了,在方法参数自定义了一个特性,用来绑定模型,优先从Form取,如果为空,或者不存在,在从QueryString中获取并且绑定,然后闲着无聊,就水一篇博客,如果大家有什么需求或者问题,可以找我,很高兴能为你们带来帮助。
总共也没有多少代码,关键其实也就是在于三个接口而已。第一个接口就是模型绑定工厂接口,继承这个接口,然后实现创建IModelBinder接口的实例即可,当然可以看到我们需要实现IModelBinder接口,在这个接口中,我们就new一个TestBinder就行了,只实现效果,不涉及业务,然后在绑定的时候会调用到BindModelAsync方法,然后在此处你可以实现自定义模型绑定,可以结合Required或者Email,MaxLength特性,结合HttpCotnext实现自己的一个模型绑定。
public class TestBinderFactory : IModelBinderFactory { public IModelBinder CreateBinder(ModelBinderFactoryContext context) { return new TestBinder(); } }
public class TestBinder : IModelBinder { public Task BindModelAsync(ModelBindingContext bindingContext) { bindingContext.Model = new TestModel() { }; bindingContext.Result = ModelBindingResult.Success(bindingContext.Model); return Task.CompletedTask; } }
在模型绑定之后,还需要实现自定义的一个验证,在默认情况下,如果使用自己去验证,且你绑定好的模型里有属性为null,则会提示the propertyname is required,就是这个属性是必须的,就需要在此处实现一个自定义验证,让通过验证,如果有需要你还需要实现IValidationStrategy接口,用来对模型内部的各个子项属性进行验证,当然如果不需要验证的话可以直接走默认的,即实现了这个接口,但不写Validate的方法体,空方法就行,如果需要就自己实现就行了,同时将自己实现的接口注入到容器,替换掉自带的就可以实现自定义模型绑定和验证了。
public class Validator : IObjectModelValidator { public Validator(IModelMetadataProvider modelMetadataProvider) { ModelMetadataProvider = modelMetadataProvider; } public IModelMetadataProvider ModelMetadataProvider { get; } public void Validate(ActionContext actionContext, ValidationStateDictionary? validationState, string prefix, object? model) { //var data=ModelMetadataProvider.GetMetadataForType(model.GetType()); //var entry=new Microsoft.AspNetCore.Mvc.ModelBinding.Validation.ValidationStateEntry(); //entry.Key = "Name"; //entry.Metadata = data; //validationState.Add("Name", entry); } }
builder.Services.AddSingleton<IObjectModelValidator, Validator>();
builder.Services.AddSingleton<IModelBinderFactory, TestBinderFactory>();
本博客仅提供思路以及部分接口实现,不涉及任何业务,如果在asp.net core中需要自定义实现什么,此处提供几个思路,
1:去api浏览器,找到对应的相关接口,传送门。
2:然后在启动的时候,在service全部注入之后,打断点,找到和你要实现自定义相关的接口或者实例即可。
3:根据第二步找到的相关注入类型,在api浏览器找到对应的,实现这个接口然后注入进去即可,源码中所有的都是tryadd,所以不用担心冲突,存在多种实现的也都是集合类型的。
4:接下来就是调试运行,就行了。
当然有能力者,可以直接去阅读源码实现即可,思路往往比具体的实现更重要。