Heim > Artikel > Backend-Entwicklung > ASP.NET-Full-Stack-Entwicklung mit serverseitiger Validierung in MVC (2)
Lassen Sie mich zunächst darauf hinweisen, dass es in diesem Blog-Beitrag um die Verwendung der serverseitigen Überprüfung in MVC geht, um die .ASP.NET-Full-Stack-Entwicklung zu verbessern. Daher werde ich nicht näher auf den wiederholten Inhalt eingehen Um es zu verbessern, basiert dieser Blog-Beitrag auf dem, was ich gelesen habe: „.ASP.NET-Full-Stack-Entwicklung mit serverseitiger Validierung in MVC“.
Obwohl wir im vorherigen Artikel die serverseitige Überprüfung abgeschlossen haben, müssen wir immer noch den Validator in der Aktion zur Überprüfung aufrufen, wie folgt.
rrreeEs ist ekelhaft, ich muss bei jeder Aktion so schreiben Wenn Sie dies in Aktion tun, werden Sie diesen Code meiner Meinung nach definitiv hassen. Zumindest denke ich das. Deshalb hasste ich die Art und Weise, wie ich es zuvor geschrieben hatte.
Was möchte ich jetzt tun? Wir wissen, dass MVC tatsächlich über eine integrierte Datenvalidierung verfügt. Ich werde es hier nicht zu sehr vorstellen (gelegentlich richtig auf das Rad zu schauen, hat viele Vorteile). Hier finden Sie eine kurze Beschreibung seiner Verwendung.
[HttpPost] public ActionResult ValidatorTest(Person model) {var result = this.ValidatorHub.PersonValidator.Validate(model); if (result.IsValid) { return Redirect("https://www.baidu.com"); }else { this.ValidatorErrorHandler(result); } return View(); }
Es ist viel schlanker als das, was wir zuvor geschrieben haben, aber ich denke immer noch, dass er immer noch ModelState.IsValid in jeder Aktion aufrufen muss Nur eines, wenn das nicht das ist, was ich will. Ich hoffe, dass es so sein kann
[HttpPost] public ActionResult ValidatorTest(Person model) { if (ModelState.IsValid) { /// ok } return View(); }
, dass es meine normale Programmierung nicht beeinträchtigt, und ich werde nicht gehen Machen Sie etwas Wiederholtes.
Mit anderen Worten, die Daten werden tatsächlich überprüft, bevor meine Aktion ausgeführt wird.
Also haben wir an den von MVC bereitgestellten Filter und OnActionExecuting gedacht. Er enthält einen Parameter ActionExecutingContext. Dieser Parameter ist ein aktionsbezogener Kontext. , dann muss er aktionsbezogene Daten installiert haben
Ich werde nicht die Tinte schreiben, sondern zuerst direkt zum Code gehen. Tatsächlich sind diese Codes genau das, was ich gerade geschrieben habe über diesen Parameter Probieren Sie sie einzeln aus, und Sie werden langsam den Dreh raus.
[HttpPost] public ActionResult ValidatorTest(Person model) { // // 一大堆代码 // return Redirect("https://www.baidu.com"); }
In OnActionExecuting definieren wir zunächst einen existError, um festzustellen, ob die Überprüfung fehlgeschlagen ist, und durchlaufen dann filterContext.ActionParameters.Values
In filterContext Wir sehen, dass es bei ActionParameters um die Parameter von Action geht. Beim Debuggen habe ich herausgefunden, dass es sich um eine Sammlung handelt, deren Schlüssel der Parametername ist.
protected override void OnActionExecuting(ActionExecutingContext filterContext) { var existError = false; foreach (var value in filterContext.ActionParameters.Values) { var modelValidatorPropertyInfo = this.ValidatorHub.GetType().GetProperty(value.GetType().Name + "Validator"); if (modelValidatorPropertyInfo != null) { var modelValidator = modelValidatorPropertyInfo.GetValue(this.ValidatorHub) as IValidator; var validateResult = modelValidator.Validate(value); if (!validateResult.IsValid) { this.ValidatorErrorHandler(validateResult); existError = true; } } } if (existError) { ViewData["Error"] = DicError; filterContext.Result = View(); } base.OnActionExecuting(filterContext); }
Es gibt Daten in der filterContext.ActionParameters-Sammlung, der Schlüssel ist „model“ und der Wert ist model
So können wir alle Parameter jeder Aktion abrufen, indem wir filterContext.ActionParameters.Value durchlaufen, und jeder Parameter kann seinen Typnamen über .getType().Name erhalten. Der Modelltyp hier ist beispielsweise Person. also ist filterContext.ActionParameters["model"].GetType().Name „Person“.
Da wir nun wissen, um welche Art von Entität es sich handelt, wie erhalten wir den spezifischen Validator? Denken Sie an unsere Validatorkonfiguration Person = PersonValidator. Das ist keine Eins-zu-Eins-Beziehung, aber es ist unmöglich, über einen Schalter zur Fabrik zurückzukehren. Natürlich nicht, dies erfordert die Verwendung der leistungsstarken Reflexionstechnologie von .NET
Manchmal haben wir ein anonymes Objekt, das ein Objekt ist, aber wir wissen nicht, um welchen Typ es sich handelt und wie wir es erhalten . Was ist mit Attributen?
Ich habe eine Methode, die dieses Problem lösen kann.
[HttpPost] public ActionResult ValidatorTest(Person model) { // // 一大堆代码 // return Redirect("https://www.baidu.com"); }
In Bezug auf die Verwendung übergeben Sie einen Attributnamen und ein Objekt und geben ein Objektattribut zurück.
Werfen wir einen Blick darauf, was intern getan wurde.
Erhalten Sie zuerst den Typ und dann das ausgeführte Attribut. Dies ist der PropertyInfo-Typ, der der Datentyp in der Reflexion ist. Aber wenn wir wollen, was soll ich tun, um den tatsächlichen Attributwert zu erhalten? Tatsächlich müssen Sie nur den Parameter „GetValue“ aufrufen. Dieser Parameter bezieht sich auf das Abrufen der Attribute für dieses Objekt. Übergeben Sie das Objekt also einfach.
Mit dieser Grundlage im Hinterkopf wissen wir, dass Person ein Objekt namens ValidatotHub mit einer Eigenschaft PersonValidator enthält, sodass wir nur die PersonValidator-Eigenschaft in einem Objekt namens ValidatorHub abrufen müssen. (Person ist ersetzbar und hängt vom Parametertyp ab. Dies wurde bereits erläutert. Hier ist Person als Beispiel.)
Jetzt gibt es ein Problem. Der PersonValidator, den wir erhalten, ist vom Objekttyp. Es ist nicht einfach für mich zu verwenden, und wir können es nicht explizit in einen bestimmten Typ konvertieren, denn wer weiß, um welchen Typ es sich handelt. Wenn es zu Tode geschrieben wird, wird es cool sein. Dann kann man es definitiv nicht mit einem Schalter warten. Würde das den Arbeitsaufwand nicht noch einmal erhöhen?
我们慢慢发现PersonValidator继承自AbstractValidator8abf60ac54173a2785e603c7a1f95b4e 很显然它的基类也需要一个具体类型,不行,继续往上走,诶,发现了AbstractValidator8742468051c85b06f0a0af9e3e506b5c继承自IValidator,并且IValidator定义了Validate方法。这不就好了吗,我as 为IValidator类型,就可以用了。这里使用了(里氏转换原则)。我尽量写得通俗易懂,也将许多基础东西提一下,但不肯能面面俱到,所以还是建立在一部分基础之上的。(当然更重要的一点是,通过这次遇到的问题让我以后在设计泛型类结构的时候,都要去继承一个非泛型的接口,如果FluentValidator没有继承自IValidator 而只是继承自IValidator8742468051c85b06f0a0af9e3e506b5c其实从简单使用上来讲,并没有什么影响啊,但到了我们刚刚这里,问题就出来了,所以这也是给我们狠狠地上了一课啊)
现在我就可以在这里进行验证了,我们知道value 就是那个model 所以直接对他进行验证,验证会返回一个ValidationResult类型接下来的事我就不解释了,相信上一章已经讲得很清楚了。最后根据是否存在错误在进行提前处理,如果有错误的话就直接返回视图呈现错误了,连咱们的Action都不执行了。好了,到这里咱们昨天讲得OnActionExecuted 可以直接Delete拉 。
我们现在把ValidatorTest里的验证代码都去掉来测试一下。
[HttpPost] public ActionResult ValidatorTest(Person model) { // // 一大堆代码 // return Redirect("https://www.baidu.com"); }
在 ValidatorTest 里打上断点,然后什么都不填,直接提交。
断点没触发,但错误消息已呈现。多试几次~.
同样没触发。
那我们来一次正确的验证。
断点触发了。并且值都通过了校验
F5放行,最终我们的页面跳转到了 www.baidu.com。
好了,小伙伴们还不快去改改代码造就幸福生活。
Das obige ist der detaillierte Inhalt vonASP.NET-Full-Stack-Entwicklung mit serverseitiger Validierung in MVC (2). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!