{
"path": "/posts/angularjs-meet-aspnet-server-validation",
"site": "at://did:plc:yy3apqjlms24kso7ahn7lbmb/site.standard.publication/3mova7c4nho2b",
"tags": [
"angularjs",
"asp.net",
"typescript"
],
"$type": "site.standard.document",
"title": "AngularJS meet ASP.Net Server Validation",
"description": "Learn how to perform server-side validation in your AngularJS and ASP.Net project using a `serverError` directive and server response error messages.",
"publishedAt": "2014-08-01T00:00:00.000Z",
"textContent": "So. You're using AngularJS to build your front end with ASP.Net running on the server side. You're a trustworthy dev - you know that validation on the client will only get you so far. You need to validate on the server.\n\n\n\nMy particular scenario is where you have a form which you are saving. Angular serves you well when it comes to hooking in your own client side validation. But it doesn't really ship with anything that supports nicely presenting server side validation on the client. Invariably when you look around you find people duplicating their server side validation on the client and presenting all their server side validation in a <div> at the top of the screen.\n\nThis works but it's not as helpful to the user as it might be. It groups together all the validation from the server into one place. What I want is field level validation from the server that's presented on a field level basis on the screen.\n\nLet us travel together to this promised land...\n\nWhat do we need client side?\n\nWell, let's start with a directive which I'll call serverError. This plants a validation message just _after_ the element being validated which is displayed when that element is declared invalid by the server. (That is to say when the ngModel has a $error.server set.) When the element is changed then the $error.server is unset in order that validation can be hidden and the form can be revalidated against the server.\n\nI'm using TypeScript with Angular so for my JavaScript examples I'll give you both the TypeScript which I originally wrote and the generated JavaScript as well.\n\nTypeScript\n\nJavaScript\n\nIf you look closely at this directive you'll see it is restricted to be used as an attribute and it depends on 2 things:\n\n1. The value that the server-error attribute is set to should be an object which will contain key / values where the keys represent fields that are being validated.\n2. The element being validated must have a name property (which will be used to look up the validation message in the server-error error \"dictionary\".\n\nTotally not clear, right? Let's have an example. Here is my \"sageEdit\" screen which you saw the screenshot of earlier:\n\nIf you look closely at where server-error is used we have a name attribute set (eg \"sage.email\") and we're passing in something called <em>vm.</em>errors as the server-error attribute value. That's because we're using the \"controller as\" syntax and our controller is called vm.\n\nOn that controller we're going to have a dictionary style object called errors. If you wanted to you could put that object on the scope instead and omit the \"vm.\" prefix. You could call it wrongThingsWhatISpottedWithYourModel or barry \\- whatever floats your boat really. You get my point; it's flexible.\n\nLet's take a look at our sageEdit Angular controller:\n\nTypeScript\n\nJavaScript\n\nOkay - this is a shedload of code and most of it isn't relevant to you. I share it as I like to see things in context. Let's focus in on the important bits that you should take away. Firstly, our controller has a property called errors.\n\nSecondly, when we attempt to save our server sends back a JSON payload which, given a validation failure, looks something like this:\n\nSo let's pare back our save function to the bare necessities (those simple bare necessities, forget about your worries and your strife...):\n\nTypeScript\n\nJavaScript\n\nAt the point of save we wipe any server error messages that might be stored on the client. Then, if we receive back a payload with errors we store those errors and set the validity of the relevant form element to false. This will trigger the display of the message by our directive.\n\nThat's us done for the client side. You're no doubt now asking yourself this question:\n\nHow can I get ASP.Net to send me this information?\n\nSo glad you asked. We've a simple model that looks like this which has a number of data annotations:\n\nWhen we save we post back to a Web API controller that looks like this:\n\nAs you can see, when ModelState is not valid we send back a dictionary of the ModelState error messages keyed by property name. We generate this with an extension method I wrote called ToErrorDictionary:\n\nThat's it - your solution front to back. It would be quite easy to hook other types of validation in server-side (database level checks etc). I hope you find this useful.",
"canonicalUrl": "https://johnnyreilly.com/posts/angularjs-meet-aspnet-server-validation"
}