Use of the six filter frame before and after the end of the separation structures scratch NetCore2.2 (EF Core CodeFirst + Autofac) + Vue item verification request data globally

He talked about how the global exception handler in NetCore project in the last article, when an interceptor processing system or manually throws an unhandled exception occurs conducted.

In this section mentioned API request a verification of the model, to throw a few questions,

    Why use model validation? Will produce some unexpected errors to my understanding, the effective average user data is not entered, it is possible to use these data in an application.

    what’s the effect? Use model validation is to ensure that requested data can be effectively used in the program, but also to avoid some unusual cases, or that you can not go to the correctness of the data in a relational model interface code, as has been verified by the model.

    how to use? MVC model validation provides better support, provides many features, you can set validation rules by Model metadata, with ModelState to handle error messages, get error messages.

Provides many built-in features in ASP.NET Core MVC in, what are some of the more commonly used built-in features:

Here are some built-in validation features:

    [CreditCard]: Verify whether the property has a credit card format.

    [Compare]: verification models two attributes match.

    [EmailAddress]: Verify whether the property has e-mail format.

    [Phone]: Verify that the property has the phone number format. Looks like we can not use this number, it is recommended to use regular properties

    [Range]: validating property values ​​are within a specified range.

    [RegularExpression]: validate the attribute value is specified regular expression matching.

    [Required]: Verify field is non-NULL.

    [StringLength]: verification string attribute value does not exceed the limit specified length.

    [Url]: Verify whether the property has a URL format.

    [Remote]: by the process operation on the call server, the authentication client input.

In addition to these built-in features can also add custom properties. For convenience example, create a custom attribute ClassicTestEqualAttribute verify field value is equal to the value built

    /// 验证值是否等于内置值
    public class ClassicTestEqualAttribute : ValidationAttribute
        private string _bulitIn;
        private string _cusValid;

        public ClassicTestEqualAttribute(string bulitIn)
            _bulitIn = bulitIn;

        protected override ValidationResult IsValid(
            object value, ValidationContext validationContext)
            var movie = (TestValidModel)validationContext.ObjectInstance;
            _cusValid = movie.CusValid;
            var cusValid = (string)value;//

Two ways to obtain the field value - value of another field may be acquired

if (_bulitIn != cusValid) { return new ValidationResult(GetErrorMessage()); } return ValidationResult.Success; } public string CusValid => _cusValid; public string GetErrorMessage() { return $"

Test model built {_bulitIn} is not equal to the value

"; } }

Then create a test model for testing

    public class TestValidModel
        [Required(ErrorMessage = "

Please enter name

"), RegularExpression("^(?!_)(?!.*?_$)[a-zA-Z0-9_]{4,12}$", ErrorMessage = "

Login does not conform to the rules, enter a 4-12 bit data does not contain special characters

")] public string Name { get; set; } [Range(22,35,ErrorMessage = "

Age should be between 22-35

")] public int Age { get; set; } [ClassicTestEqual("test")] public string CusValid { get; set; } [StringLength(3,ErrorMessage = "

In length for the character string within 3

")] public string Role { get; set; } [Required(ErrorMessage = "

Please enter the message

")] [EmailAddress(ErrorMessage = "

Incorrect format

")] public string Email { get; set; } [Required(ErrorMessage = "

Please enter the phone

"), RegularExpression("^1[3|4|5|6|7|8|9][0-9]{9}$", ErrorMessage = "

Phone number is not formatted correctly

")] public long Phone { get; set; } }

This time to add a test method, and then call interface by Postman, call our body when nothing Chuan try. PS: Postman is an excellent interface test software.

Here we can see the model validation has failed, and the number of errors as to why only five, because has been restricted in the Startup category, the maximum number of validation errors only five.

services.AddMvc MaxModelValidationErrors to change.

services.AddMvc(options =>
                options.MaxModelValidationErrors = 5;//

The maximum number of validation errors

options.AllowValidatingTopLevelNodes = true;//

Verify whether to allow the top node interface method parameters

options.Filters.Add(new ExceptionFilter());//

Add exception processing filter


When an incoming request data interface to meet the requirements of model verification will pass.

Here it is available from ModelState in an error message, but to demonstrate the effect of model validation would not write. You can not always be done when model validation are so to write code like this again, so we use filters to request global model validation.


First, we add model validation methods, inherited property ActionFilterAttribute

    /// 模型数据验证
    public class ModelValid : ActionFilterAttribute
        public override void OnActionExecuting(ActionExecutingContext filterContext)

Determining whether the model is verified by

if (filterContext.ModelState.ErrorCount == 0 && filterContext.ModelState.IsValid) return; var errMsg = new StringBuilder(); foreach (var modelStateKey in filterContext.ModelState.Keys) { var value = filterContext.ModelState[modelStateKey]; foreach (var error in value.Errors) { if (!string.IsNullOrEmpty(error.ErrorMessage)) { errMsg.Append(error.ErrorMessage + ","); } } } if (errMsg.Length > 0) { errMsg.Remove(errMsg.Length - 1, 1); } if (filterContext.Controller is BaseController controller) filterContext.Result = controller.Fail(1005, $"

Request data fails verification, {errMsg}


Error Code 1005 is a custom

else throw new CustomSystemException("

Default Controller should inherit BaseController, in order to achieve a global model validation, error remind


Error Code 999 is a custom

} }

Then the model validation filter property is added to the base class BaseController controller, because each controller will inherit the controller, and this model validation filter triggers on every request.


After this addition was complete model will be validated when accessing each interface. At this time of the previous model test method to determine commented out, then re-run the test access interface facie effect?

There’s only complete when the model validation process to go through the business logic will. Otherwise it will not be implemented business model will directly return the validation error messages. PS: The above is worth saying is, why did not lose a phone number, will not return “Please enter a phone number.” Because long type is not NULL, so when there is no input phone numbers, phone field is the default, namely Phone = default (long) // 0 Only long type into long? Or can at no time Nullable trigger Required characteristics enter a phone number. As it has been changed to be the empty type.

Above is carried out before performing verification model, we can also verify that the data model to meet the requirements again after performing a series of business logic, as long as the execution TryValidateModel (validModel); can be.

Test interface method into the following:

        public ActionResult ValidModel([FromBody]TestValidModel validModel)
            //            if (!ModelState.IsValid)
            //            {
            //                return Fail(1005, "模型验证失败");
            //            }
            validModel.Age = 18;
            var b = ModelState.IsValid;
            return Succeed("


"); }

Then again visited by the above model of success, debugging break point can be verified result is false, in fact, in this place can be re-validated method to the base class to the controller, if the validation fails, the validation fails direct return results.

In addition to model validation, verification can be top-level node, which is the interface method parameter on direct verification. But generally not recommended for this use. You have to do a little change in the Startup category, above the code has been posted out. Sample code is as follows:

        [AcceptVerbs("Get", "Post")]//

Allow get and post method

[Route("validphone")] public ActionResult TestValid([Required(ErrorMessage = "

Please enter your phone number

")] [RegularExpression(@"^1[3|4|5|6|7|8|9][0-9]{9}$", ErrorMessage = "

Not a valid phone number

")] string phone) { //phone = "123"; //TryValidateModel(phone);//

The single field-based methods should be used invalid

if (!ModelState.IsValid) { var errMsg = new StringBuilder(); foreach (var modelStateKey in ModelState.Keys) { var value = ModelState[modelStateKey]; foreach (var error in value.Errors) { errMsg.Append(error.ErrorMessage + ","); } } errMsg.Remove(errMsg.Length - 1, 1); return Fail(1, errMsg.ToString()); } return Succeed("


"); }

Implementation of the results is not a map, as long as everything after his own attempt will understand.


The next one will be how to generate NetCore by jwt token, and token authentication, refresh and other personal thoughts.


Need source code under comments or private letter to me ~ SVN guest account password to download the code is not on GitHub.


Leave a Reply