Angular JS Form Validation using ModelState in Web API

I am working on a client side web application in AngularJS, TypeScript and HTML, and the server side is the .NET Core web interface.

I want to implement server side validation using ModelState and DTO. The fact is that I do not want to display all validation errors at the top of the form, but I want to display them in a line with a text field

enter image description here

So, first I added validations to the DTO, and then checked the controller on ModelState.IsValid

 public class TestDTO { [Required(ErrorMessage = "This field is required")] public string TestName { get; set; } } public class ManyTestDTO { [Required(ErrorMessage = "Many Item is required")] public string ManyItem { get; set; } } public class RestaurantDTO { public int RestaurantId { get; set; } [Required(ErrorMessage = "This field is required")] public string Name { get; set; } [Required(ErrorMessage = "This field is required"), MaxLength(20), MinLength(1)] public string Description { get; set; } [Required(ErrorMessage = "This field is required")] public string Address { get; set; } public TestDTO TestModel { get; set; } public List<ManyTestDTO> TestMany { get; set; } public RestaurantDTO() { } } 

Getting the idea from this link: Link - I created a directive in my application to display the verification message in a line, this works fine, the problem is that the HTML that I write to display the verification message is complicated.

Directive

 export class ServerValidationDirective implements ng.IDirective { constructor() { } restrict: "A"; require: "ngModel"; link = function (scope, element, attrs, ctrl) { scope.$watch("controller.modelState", () => { let modelState = scope.controller.modelState; console.log(modelState); if (modelState == null) return; let state = modelState[attrs.ngServerValidate]; if (state) { // Server Errors exist for the ngServerValidate scope.controller.parsedModelState[attrs.ngServerValidate] = state; } else { // No Error for the ngServerValidate if (scope.controller.parsedModelState[attrs.ngServerValidate]) { scope.controller.parsedModelState[attrs.ngServerValidate] = null; } } }); }; static factory(): ng.IDirectiveFactory { var directive = () => new ServerValidationDirective(); return directive; } } 

Controller:

 class CreateRestaurantController { static $inject = ["$scope"]; restaurantModel: any; modelState: any; parsedModelState: any; testModelState:any; constructor($scope) { this.scope = $scope; // create a local copy of the $scope this.scope.controller = this; //put controller reference in this.scope.controller this.restaurantModel = {name: "Dawood",testModel: {},testMany: [{ ManyItem: "I have a Value" },{}]}; this.modelState = null; this.parsedModelState = {}; this.testModelState = JSON .parse('{"Address":["This field is required"],"Description":["This field is required"],"TestModel.TestName":["This field is required"],"TestMany[1].ManyItem":["Many Item is required"]}'); console.log(this.testModelState); } testValidation() { this.modelState = this.testModelState; //Normally modelStae will be return from server // Submit to Server //this.apiService.post("/api/RestaurantDashboard/GetTestValidation", // null, this.restaurantModel, // response => { // console.log(response); // }, // response => { // this.modelState = response.data; // }); } } 

HTML for the form

 <div ng-app="validationApp"> <div ng-controller="validationController"> <form name="restaurantForm" class="form"> <div class="form-group" ng-class="{'has-error': controller.parsedModelState.Name != null}"> <label>Restaurant Name</label> <input type="text" class="form-control" ng-server-validate="Name" ng-model="controller.restaurantModel.name"> <span class="help-block" ng-repeat="errorMessage in controller.parsedModelState.Name"> {{errorMessage}} </span> </div> <div class="form-group" ng-class="{'has-error': controller.parsedModelState.Address != null}"> <label>Address</label> <input type="text" class="form-control" ng-server-validate="Address" ng-model="controller.restaurantModel.address"> <span class="help-block" ng-repeat="errorMessage in controller.parsedModelState.Address"> {{errorMessage}} </span> </div> <h3>Nested Object</h3> <div class="form-group" ng-class="{'has-error': controller.parsedModelState['TestModel.TestName'] != null}"> <label>TestModel.TestName</label> <input type="text" class="form-control" ng-server-validate="TestModel.TestName" ng-model="controller.restaurantModel.testModel.testName"> <span class="help-block" ng-repeat="errorMessage in controller.parsedModelState['TestModel.TestName']"> {{errorMessage}} </span> </div> <h3>Many Array/List</h3> <ul class="list-unstyled"> <li ng-repeat="item in controller.restaurantModel.testMany"> <div class="form-group" ng-class="{'has-error': controller.parsedModelState['TestMany[' + $index + '].ManyItem'] != null}"> <label>Many Item {{$index}}</label> <input type="text" class="form-control" ng-server-validate="{{'TestMany[' + $index + '].ManyItem'}}" ng-model="item.ManyItem"> <span class="help-block" ng-repeat="errorMessage in controller.parsedModelState['TestMany[' + $index + '].ManyItem']"> {{errorMessage}} </span> </div> </li> </ul> <button class="btn btn-primary" ng-click="controller.testValidation()">Click Me to Check</button> </form> </div> </div> 

As you can see, the HTML structure for Many Array/List and Nested Object bit complicated. Is there a better way to do this?

Fiddle: https://jsfiddle.net/mdawood1991/ua9mk7qz/

+5
source share

Source: https://habr.com/ru/post/1258205/


All Articles