引言
水此篇部落格,依舊是來自群裡的討論,最後說到了,在方法引數自定義了一個特性,用來繫結模型,優先從Form取,如果為空,或者不存在,在從QueryString中獲取並且繫結,然後閒著無聊,就水一篇部落格,如果大家有什麼需求或者問題,可以找我,很高興能為你們帶來幫助。
IModelBinderFactory
總共也沒有多少程式碼,關鍵其實也就是在於三個介面而已。第一個介面就是模型繫結工廠介面,繼承這個介面,然後實現建立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; } }
IObjectModelValidator
在模型繫結之後,還需要實現自定義的一個驗證,在預設情況下,如果使用自己去驗證,且你繫結好的模型裡有屬性為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:接下來就是除錯執行,就行了。
當然有能力者,可以直接去閱讀原始碼實現即可,思路往往比具體的實現更重要。