Dynamic data validation in ASP.NET MVC - asp.net-mvc

I've recently read about the model validation capabilities of ASP.NET MVC which are all very cool until a certain point. What happens if the application doesn't know the data that it works with because it is all stored in DB and built together at runtime. Just like in Drupal, I'd like to be able to define custom types at runtime, and assign runtime validation rules as well. Obviously, the idea of assigning attributes to well established models is now gone. What else could be done ? I am thinking in terms of rules being stored as JSON objects in the DB fields or something like that.

Have you looked at the jquery validation plugin? One of the options you have there is to declare your UI validation in Javascript. For example for my contact page I have the following validation being used.
$(document).ready(function () {
$("#ContactForm").validate({
rules: {
Name: "required",
Email: {
required: true,
email: true
},
Subject: "required",
Message: "required"
}
});
});
This is a very baisc usage of the plugin.
Obviously you will still need some sort of backend validation, but for you UI this sounds ideal to your scenario.

Related

Where do i place my viewmodel validation?

we are building an ASP.Net MVC application, and we ask ourselve the question where we shoud put the validation logic for incoming data.
We already have the simple validation in place: these are attributes on the viewmodel, like [required], [numeric] , [email] etc. (this is open for discussion too, btw)
But now we have some more input validation: we want to validate if the id's received from dropdownlists are genuine id's.
For example: when we receive 91 as a countryid, i have to make sure 91 is a valid countryid and not a value 'hacked into' the form by a user. Because if it is not a valid countryid, my datalayer generates an error.
Should i place this in the controllers action method, because that
method knows what is right and what is wrong when the data from the request arrives?
Should i place it in a VacancyValidator (the object is a Vacancy
object) where i put all validation logic for all vacancy related
viewmodels
Should i place it in the ViewModel because it should know how to validate itself
Should i create an attribute which validates the property which i place on the ViewModels property
Should i place it in a Vacancy[thisviewmodelsname]Validator where i put all validation logic for this specific viewmodel
Any ideas appreciated....
We already have the simple validation in place: these are attributes
on the viewmodel, like [required], [numeric] , [email] etc. (this is
open for discussion too, btw)
I would recommend FluentValidation.NET instead of Data Annotations which plays nicely with ASP.NET MVC. It provides a nice syntax for expressing complex validation logic between interdependent properties without writing millions of lines of plumbing infrastructure code (which is what you would have to do if you use Data Annotations and write a custom validator) and also allows you to unit test your validation logic very easily.
Because if it is not a valid countryid, my datalayer generates an error.
There you go - your data layer already handles this validation for you. But if you don't want to leave it to reach the data layer then you could have a validation rule for this property on the view model. If you follow my previous advice about FluentValidation.NET you will already know where to put this rule - in the corresponding validator of your view model.
You put your validation obviously to the view model. This way it is located in one spot (not scattered, hence DRY) and operational on both client and server.
For simple scenarios use Data Annotations.
For more sophisticated scenarios (enterprise scale etc) use Fluent Validation
Hope this helps.
The best way is to combine client and server validation. For client side validation you can use jquery validation plugin. It provides all standart validation patterns(like maxlength, minlength, required etc.).You can specify validation requirements in model attributes(data annotation) or directly in html. Also, it provides possibility for custom remote validation when validation result will be returned from server code.
But you should dublicate client side validation with server side. For example, use spring.net validation . I think it's the best generic and flexible framework.

Display errors using Knockout JS + MVC + Server-side Model Validation?

Html form is controlled using Knockout JS and jQuery templates.
Basic jQuery validation is in use to validate fields.
Form gets serialized to JSON and submitted to MVC controller action using AJAX.
MVC controller action performs server-side model validation, adds errors to ModelState.
What's the best practice to return those errors to the client - iterating through errors in ModelState and adding them to key/value collection of errors in the JSON response?
How do you display errors on the client? How do you 'bind' the key/value collection of errors to relevant fields on the model?
Say there is a "name" field on the model, with a corresponding textbox rendered by the jQuery template. How does one take the error for the "name" field in the collection of errors and display the error message beneath the "name" textbox?
There's two validation plugins for ko.js (found here) that could help you,
Knock-Knock validation
Knockout Validation
You can wire one of those to the mvc unobstrsive validation data injected client side.
If you are using MVC, unobtrusive javascript performs client side validation based on the validation set in your model. You need not perform any additional configuration.
Having said that, there is no direct way to perform client side validation based on the model using javascript and knockoutjs.
There are couple of ways of doing it on the client side.
Jquery or any other validation frameworks can perform validation. But you need to have tag. Advantage with this approach is your code will be simple and easy to maintain.
You can perform client side custom validation using javascript and bind the validation messages using knockout. This requires you to create error labels for each of the input variable. Advantage with this approach is you will have complete control over how and what has to be displayed.
Personally, I had similar requirement in one of the recent projects and I achieved it using custom validation checks and error labels.

Simple Validation for a Single Text Box in ASP.NET MVC

I have added a text box to a simple form in ASP.NET MVC and I want a client-side 'required' validation for this.
I know I can do this using a strongly typed model view but I would like to do it manually in this case. Is there a simple way to perform this?
I tried setting the Model/property name of the Html.ValidationMessage helper to the input name but this didnt work:
#Html.TextBox("emailStr" )
#Html.ValidationMessage("emailStr","* Required")
Assuming you use default jQuery validation plugin, you can use Rules.Add method on client side for this
$("#emailStr").rules("add", {
required: true,
messages: {
required: "* Required",
}
});
Also, do not forget to include jquery.validate.min.js
Not sure why you would want to do it manually - but I don't think you can use #Html.ValidationMessage unless you use a TextBoxFor. You can't use the TextBoxFor unless you have a model to work with inside the view.
You could write some javascript/jquery to find the textbox and make sure it's not empty, and if it is, unhide an element with the validation message in it.

Knockout + mvc 3 + Validation

In the controller I would like to be able to get to the client validation rules of the model. I've attached some attributes using data annotations and would like to be able to pass something back to the client via the ajax call so I can then build the jquery validate options automatically.
Normally this is done for free with the unobtrusive stuff, but I'm trying to leverage knockout binding, while still not having to replicate the validation rules on both the server and client.
Without using reflection on the model server side I'm a little unsure on how to achieve this.
In my Mvc Controls Toolkit I developed Helpers based on the knockout library. These helpers not only help in writing the knockout code, but enhance the knockout library with Unobtrusive validation and globalization. Moreover, the binding mechanism is enhanced to include complex controls such as a DatetimePicker, and other "complex" (made by different html parts) controls.
Finally, knockout templates can be defined through Razor helpers.
See the documentation here, here, here and here. I also have some tutorials that show how to implement advanced features with my helpers:
Low BandWidth Transfers with The Client Side Templates of the Mvc Controls Toolkit
Handling Big Amounts of Data with Client-Side Templates
Handling Big Amounts of Data with Client-Side Templates 2
Depeneding on what you exactly need to do, Breeze js can be the best solution. particularly, if you're using EF, you can replicate most of the functionality of the server EF's DbContext on the client side, including, of course, the validation, but also change tracking, .saveChanges, a simple syntax that resembles LINQ queries, caching, serializing and deserializing to allow working offline, and many other things.
The basic steps to work with Breeze js are:
create an EF model in the server
add a NuGet Package on the server to create Web API Services that expose the model to the client side. This is done with a surpringly low number of C# code. One of the things that this does is exposing the metadata: definition of objects, relations, and extra information, like data annotations validation info
add a js Nuget Package for the client side which will be used to replicate the EF behavior on the client side.
Of course, not all of the functionality on the server will be replicated on the client, but you can do a lot of things:
create new entities on the client side
make queries on the client side, which will be executed on the server and returned to the client
modify entities on the client: create, modify, delete...
create relations on the client side: for example create new chlid entities in a parent object
call saveChanges on the client side, which will transfer all the tracked changes to the server so that the backend is updated
of course, while you do this, you'll get automatic client validation, and also additional server validation whenever you call .saveChanges
Finally, you can extend and modify the server code to include some business logic, so that you can do much more than simply exposing the EF model to the client.
That's quite a task. You want to be able to convert your C# code into Javascript with respective data type conversions etc. You'll be better off writing down two separate sets of validation at server and client side both. It would be a lot more easier to maintain that than to write your own conversion framework all by yourself and maintaining it
On the model use attributes validation that you like:
public class ModelWithValidation
{
public int Id { get; set; }
[Required]
public string Name { get; set; }
}
In mvc forms
#using( Html.BeginForm())
{
#Html.TextBoxFor(m => m.Name, new {data_bind = "value: name"})
#Html.ValidationMessageFor(m => m.Name)
}
In jQuery test if form is valid onSubmit or in knockout save function call the next code to validate input. You must include jQuery.unobtrusive* and jQuery.validate* libraries. Don't forget to validate input on server side also!
var form = $("form");
form.removeData('validator');
form.removeData('unobtrusiveValidation');
$.validator.unobtrusive.parse(form);
$("form").valid() //true false

With an MVC application should my business rule validation be replicated in the view model and/or controller?

My MVC application has a well defined domain Model with each Model performing its own business rule checks.
My question is should the business rules be replicated in the view model or controller too or should I just allow the model to generate the validation errors?
Lets assume that the validation we are talking about can't be done client-side and is more complicated than simple field validation that can be done by adding validation attributes to the view model properties.
The problem with allowing the model to handle all of the validation is that the error messages it generates might not be suitable for the particular view that its coupled to, field names might not be correct for example. Also I need to add the error to the ModelState using the view model property name not the property name from the domain model.
The problem with adding the same business rule validation to the viewmodel/controller is the obvious duplication maintenance issue and it means the validation in my domain model really should never produce any errors which kind of makes it a bit pointless.
How do people usually handle this?
The solution I typically used to use in this scenario is to have the validation in the Model (or in my case typically a validation library) but add the error in the controller which allows you to catch the standard validation error like this:
public ActionResult Submit(String email)
{
string errorMessage = "";
if(Validation.IsValidEmail(email, out errorMessage))
{
ViewData.AddModelError("EmailAddress", "My Custom Error Message");
//or
ViewData.AddModelError("EmailAddress", errorMessage);
}
}
This may not be exactly what you are looking for but it might help you come up with a way of maximising re-usable code whilst still being able to customise it.
I used to do it like this - but I bit the bullet and my most recent applications use standard error messages everywhere - my motivation for this is that users are increasingly comfortable with short-simple validation message and field names are not required in the message if the message is displayed inline with the form field rather than as a summary. This also allows me to put all my rules/messages in data annotations and I find that it works a treat.

Resources