【asp.net core】自定義模型繫結及其驗證

2023-05-09 18:02:41

引言

    水此篇部落格,依舊是來自群裡的討論,最後說到了,在方法引數自定義了一個特性,用來繫結模型,優先從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:接下來就是偵錯執行,就行了。

    當然有能力者,可以直接去閱讀原始碼實現即可,思路往往比具體的實現更重要。