unobtrusive validation with custom validator that requires ajax post - asp.net-mvc

I'm using ASP.NET MVC with unobtrusive validation. I need to add a new custom validation attribute with client-side validation, which is fine (I've already got some of those defined). The problem is that in the client side validation, I need to make an ajax call to check if the input is valid.
In MVC, you add client-side validators with addMethod:
jQuery.validator.addMethod("customValidation", function(){...})
But the function you define needs to return a boolean, and doing an ajax post is aysnc, which breaks that.
According to jQuery validator and a custom rule that uses AJAX there are 2 options - either use async:false in the ajax call or add a remote to the validate method. BUT, async:false is depcrated and I can't use remote because I'm using unobtrusive validation.
Has anyone got any better solutions to this?

Data annotations contain a Remote attribute that plugs into jquery remote validation automatically.
https://msdn.microsoft.com/en-us/library/system.web.mvc.remoteattribute(v=vs.98).aspx

Related

Nested jQuery AJAX calls with dependencies using MVC 3 and razor

I am using an MVC 3 Ajax.BeginForm call for form submission with client side validation. One of the input fields is a postcode (postalcode) and as well as validating the format I also want to check to see if it exists in a database table of approximatley 2 million entries.
The solution I chose was to use the an BeginForm OnBegin call to perform a lookup before submission and if the postcode does not exist offer the user the options of accepting it or re-entering. I am performing the postcode lookup using another Ajax call
The problem is that I need to wait for the the inner Ajax call to return and process the response before returning to the outer call but as this is an asynchronous call the function is continusing before the inner Ajax has completed.
I can see several non-preferred solutions, e.g. making the inner Ajax call synchronous or catching the submit button click event but does anyone have suggestions for a clean unobtrusive solution.
Thank you.
You could use the [Remote] attribute to perform remote validation. You simply decorate the corresponding property on your view model with this attribute and then specify the controller action that will perform the actual validation.
Obviously no matter which solution you choose you absolutely must perform the same check once the form is submitted on the server because by the time you initially checked with AJAX and the time the form is actually submitted your database data could change and what was valid initially be no longer valid.

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.

Asp MVC unobtrusive Client Validation always returning true

We have a partial view that contains a form with unobtrusive client validation enabled.
If we load the partial view using Html.Action, the validation works on the client side.
If when the user clicks a link we use JQuery to populate a div with the partial view , the client validation always returns true.
Any idea what is going on?
You need to parse the new html to hook up the validation controls. You can do this using:
$.validator.unobtrusive.parse( $('.selector' ) );
where the selector returns the container holding the new HTML. This is what I use with tabbed interfaces.

Validating posted form data in the ASP.NET MVC framework

I've been playing around with the ASP.NET MVC Framework and the one thing that's really confusing me is how I'm meant to do server side validation of posted form data. I presume I don't post back to the same URL, but if I don't, how do I redisplay the form with the entered data and error messages? Also, where should the validation logic go? In the model or the controller? This seems to be one of the few areas where web forms are much stronger (I miss the validation controls).
Here's an overview of the flow in MVC:
/new - render your "New" view containing a form for the user to fill out
User fills out form and it is posted to /create
The post is routed to the Create action on your controller
In your action method, update the model with the data that was posted.
Your Model should validate itself.
Your Controller should read if the model is valid.
If the Model is valid, save it to your db. Redirect to /show to render the show View for your object.
If the Model is invalid, save the form values and error messages in the TempData, and redirect to the New action again. Fill your form fields with the data from TempData and show the error message(s).
The validation frameworks will help you along in this process. Also, I think the ASP.NET MVC team is planning a validation framework for the next preview.
You might want to take a look at ScottGu's latest post for ASP.Net prev 5. It walks through a validation sample that is very interesting:
http://weblogs.asp.net/scottgu/archive/2008/09/02/asp-net-mvc-preview-5-and-form-posting-scenarios.aspx
As far as I can tell everyone is still trying to figure out the "standard" way of doing it. That said definitely check out Phil Haack and Scott Guthrie's latest posts on MVC and you'll find some interesting info on how they did. When I was just playing around with it for myself I created a ModelBinder for the LinqToSql data class that I had generated. You can check out this post to find out how to put together a basic ModelBinder:
ASP.Net MVC Model Binder
The in your action if you had created a "Product" ModelBinder you would just declare the action like so:
public ActionResult New(Product prod)
And the model binder will take care of assigning posted data to the objects properties as long as you've built it right anyway.
After that within your GetValue() method you can implement whatever validation you want, whether using exception's, regex's, or whatever you can make a call like:
(ModelStateDictionary_name).AddModelError("form_element_id", "entered_value", "error_message");
Then you can just throw a <%= Html.ValidationSummary() %> in your view to display all your errors.
For client-side validation I just used jQuery. After you get a basic sample set up though you can start doing some interesting things combining all that with Partial Views and Ajax calls.
Have you taken a look at this?
http://www.codeplex.com/MvcValidatorToolkit
Quoted from the page
The Validator Toolkit provides a set
of validators for the new ASP.NET MVC
framework to validate HTML forms on
the client and server-side using
validation sets.
I'm afraid that someone more MVC-savvy than me would have to speak to where in the architecture you should put things.
I'm just learning the MVC framework too so I'm not sure how off this is, but from what I understand you would have a form on a View such as Edit.aspx. This form would then post to the controller to another action method such as Update() passing in the contents of the form that you set in Edit.aspx as parameters.
Update(int id, string name, string foo)
You could do the validation within that method. If all is ok,
return View("Item", yourObject)
There is Castle.Components.Validator module in Castle project. It's very agile and powerfull. It generates validation rules based on model attributes (or any other source) and even able to generate JS validation using jQuery, Prototype Validation, fValidate and other.
Of course it's wise to abstract validator away behind IValidationEngine interface.

Resources