집 >백엔드 개발 >C#.Net 튜토리얼 >MVC에서 서버측 유효성 검사를 사용한 ASP.NET 전체 스택 개발(2)
우선 이 블로그 게시물은 .ASP.NET 풀스택 개발을 개선하기 위해 MVC에서 서버 측 검증을 사용하는 것에 관한 것이므로 반복되는 내용에 대해서는 자세히 설명하지 않겠습니다. 그런 다음 이를 개선하세요. 이 블로그 게시물은 "MVC에서 서버 측 확인을 사용하여 .ASP.NET 전체 스택 개발"을 읽은 내용을 기반으로 동일합니다.
이전 글에서는 서버측 검증을 완료했지만, 이렇게 검증을 위해 Action에서 Validator를 호출해야 합니다.
[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(); }
역겹습니다. 모든 Action에 이렇게 써야 합니다. 정말 모든 Action에서 이렇게 해야 합니다. 여러분은 분명히 이러한 코드를 싫어할 것입니다. 적어도 나는 그렇게 생각한다. 그래서 예전에 썼던 방식이 싫었어요.
나는 지금 무엇을 하고 싶은가? 우리는 MVC에 실제로 데이터 유효성 검사 기능이 내장되어 있다는 것을 알고 있습니다. 여기서는 자세히 소개하지 않겠습니다(가끔 휠을 제대로 보면 장점이 많습니다). 다음은 사용법에 대한 간략한 설명입니다.
[HttpPost] public ActionResult ValidatorTest(Person model) { if (ModelState.IsValid) { /// ok } return View(); }
이전에 작성한 것보다 훨씬 간소화되었지만 여전히 모든 Action Call ModelState에 작성해야 한다고 생각합니다. .IsValid in, if는 하나만 있지만 이것이 내가 원하는 것은 아니지만 이렇게 되기를 바랍니다. 일반적인 프로그래밍에 영향을 주지 않으며 반복적인 작업을 수행하지 않습니다.
즉, 내 Action을 실행하기 전에 실제로 데이터를 검증하는 것입니다.
그래서 우리는 MVC에서 제공하는 필터인 OnActionExecuting을 생각하고 그 안에 OnActionExecuting을 다시 작성했습니다. 여기에는 ActionExecutingContext라는 매개변수가 있습니다. .컨텍스트라면 액션 관련 데이터를 설치했을 것입니다
잉크를 쓰지 않고 먼저 코드로 직접 이동합니다. 사실 이 코드는 제가 방금 작성한 것입니다. 저는 이 매개변수에 대해 잘 모릅니다. 하나씩 시도해 보면서 점차 알아냈습니다.
[HttpPost] public ActionResult ValidatorTest(Person model) { // // 一大堆代码 // return Redirect("https://www.baidu.com"); }
OnActionExecuting에서는 먼저 기존 오류를 정의하여 확인 실패 여부를 확인한 다음, ActionParameters.Values를 순회합니다.
filterContext에서 ActionParameters는 Action의 매개변수에 관한 것임을 알 수 있습니다. 디버깅을 통해 이것이 매개변수 이름이 키인 컬렉션이라는 것을 알았습니다.
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); }
filterContext.ActionParameters 컬렉션에 데이터가 있으며 키는 "model"이고 값은 model#🎜🎜입니다. ##🎜 🎜#
따라서 filterContext.ActionParameters.Value를 순회하여 각 Action의 모든 매개변수를 검색할 수 있으며, 각 매개변수는 .getType().Name을 통해 이를 검색할 수 있습니다. 예를 들어 여기서 모델 유형은 Person이므로 filterContext.ActionParameters["model"].GetType().Name은 "Person"입니다. 이제 엔터티의 유형을 알았으니 특정 유효성 검사기를 어떻게 얻을 수 있나요? 유효성 검사기 구성인 Person = PersonValidator를 생각해 보세요. 이는 일대일 관계가 아니지만 이 경우 팩토리 메서드를 유지해야 합니다. 물론 그렇지 않습니다. 이를 위해서는 .NET에서 제공하는 강력한 리플렉션 기술을 사용해야 합니다. 때로는 객체인 익명 객체가 있지만 그것이 어떤 유형이고 어떻게 수행하는지 모릅니다. 그것을 검색합니다. 그 속성은 무엇입니까?이 문제를 해결할 수 있는 방법이 있습니다.
[HttpPost] public ActionResult ValidatorTest(Person model) { // // 一大堆代码 // return Redirect("https://www.baidu.com"); }
사용상 속성명과 객체를 전달하고 객체의 속성을 반환합니다.
내부적으로 어떤 일이 이루어졌는지 살펴보겠습니다.
먼저 유형을 얻은 다음 실행된 속성을 가져옵니다. 아, 이 속성은 실제 속성이 아니며 리플렉션의 데이터 유형입니다. 값이 있지만 실제 속성 값을 얻으려면 어떻게 해야 할까요? 실제로 GetValue를 호출하기만 하면 됩니다. 여기에는 매개변수가 있습니다. 이 매개변수는 해당 개체의 속성을 가져오는 것을 참조하므로 개체를 전달하기만 하면 됩니다.
이 기반을 바탕으로 Person을 아는 목적을 되돌아보면 ValidatotHub라는 개체에 PersonValidator 속성이 포함되어 있으므로 ValidatorHub라는 개체에서 PersonValidator 속성만 가져오면 됩니다. (Person은 교체 가능하며 매개 변수 유형에 따라 다릅니다. 이전에 설명했습니다. 여기에는 Person이 있습니다.)
이제 문제가 발생합니다. 우리가 얻는 PersonValidator는 객체 유형입니다. 는 제가 사용하기 쉽지 않고, 특정 유형이 무엇인지 누가 알기 때문에 특정 유형으로 명시적으로 변환할 수 없습니다. 죽음에 쓰이면 멋질 것입니다. 그렇다면 그것을 유지하기 위해 스위치를 사용할 수는 없을 것입니다. 그러면 작업량이 다시 증가하지 않을까요?
我们慢慢发现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。
好了,小伙伴们还不快去改改代码造就幸福生活。
위 내용은 MVC에서 서버측 유효성 검사를 사용한 ASP.NET 전체 스택 개발(2)의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!