I am using AjaxSubmit to post a form and there are server side validations done using XVal (RuleException way). I am not using the try/catch way to add error to Model and then send to view. Instead - I want to use the HandleError attibute and in the OnException I am adding the errors to Model. The major problem is how do I get those errors as a results in the Ajax Call?
There is not a great solution built in right now. Doing this correctly requires a client-side validation framework (because, to display the errors, you need to dynamically change the HTML page), and until recently, ASP.NET MVC has not had that. However, ASP.NET MVC 2 Preview 2 introduced client-side validation, so it's reasonable to presume that something might be built into the framework soon.
In the meantime, however, HandleErrorAttribute won't help you. HandleErrorAttribute only knows how to redirect to an error page, which is generally not what you want to do in response to a server-side validation error even with a "normal" POST, and certainly not with an AJAX post.
There really two different scenarios you need to handle:
Validation errors are not catastrophic failures; they are simply bad user data, which you should expect. You just need to get the information back to the page, so that the page can be marked up to tell the user how to fix their data.
You also need to handle catastrophic failures, like unanticipated exceptions. This is akin to what HandleErrorAttribute does, insofar as you can display a message to a user, but you cannot necessarily match that message up with specific fields on your page.
To handle the first scenario of error, you need to wrap the model state up into an object which will be parsable in JavaScript code; JSON is the obvious fit here. You then need to have JavaScript code on the client side which parses this object and marks up the form fields. This is easier if you tie into an existing client-side validation framework, which already contains code for marking up form fields.
To handle the second type of error, you can extend HandleErrorAttribute in order to provide JSON instead of HTML in the event of a catastrophic failure. Again, you will need to write JavaScript code that will be executed in the event of a failure -- jQuery's global ajaxError event is useful here -- that detects this structured error information you've created and display some sort of useful message to the user.
If all this sounds a bit involved, well, it is, which is why it may make more sense to wait and see what will be built-in when MVC 2 is finally released.
Related
I want to allow users to add validation rules in the database, for example 'Password cannot be the same as username' or something like that. I know how to validate these rules server side, but I would like to have a set of validators available which can be set at runtime, and also work client-side.
I want to validation process to be handled as close to the MVC standard as possible. One thing that crossed my mind is to set attributes at runtime, but I'm not sure if this is the way to go.
For now, we have the validation working at runtime and pass validation messages back to the client using Json, which works fine, but requires a (async) postback. If we can implement client side validation, we can eliminate the validation postback which boosts the application's performance but again, i'm not sure which way to go. Anyone with some good thoughts?
did you try remote validation attribute? if you need lookup in database, you need ajax.
http://msdn.microsoft.com/en-us/library/gg508808(v=vs.98).aspx
I am using ASP.NET MVC3 with jQuery Validate + the unobtrusive validation support that comes with MVC3. Works great for almost everything, but I have one view where there is some view-wide validation that I need to do and I am not sure how to tap into the validation events that happen as part of MVC3+Validate+Unobtrusive. The actual validation will take just a few lines of code. I just don't know where to plug in that code.
I would like to tie into existing validation flow so that when the standard validation finds errors with individual fields and adds warning messages for them, my form-wide error message will also appear in the validation summary.
P.S. I am clear how to add appropriate model-level validation on the server side (Scott just blogged about it), but I feel it would be strange if some validation happened on the client and others only on the server. A user might see the client validation errors, fix them, then try to submit the form and only then get the model-level validation error message.
I would say what you are looking for is the new support for Remote Validation in Asp MVC3. Here is an article describing a common scenario, hopefully you can extend it yourself. Otherwise there are probably other articles around explaining it even better ;-)
http://www.aaronstannard.com/post/2010/12/07/remote-validation-asp-net-mvc3.aspx
/Victor
You should ALWAYS validate again on the server. Its really easy to circumvent javascript validation.
Rule #1 of Web Development: NEVER TRUST USER INPUT
I'm after some design advice.
I'm working on an application with a fellow developer. I'm from the Webforms world and he's done a lot with jQuery and AJAX stuff. We're collaborating on a new ASP.MVC 1.0 app.
He's done some pretty amazing stuff that I'm just getting my head around, and used some 3rd party tools etc. for datagrids etc.
but...
He rarely uses Submit buttons whereas I use them most of the time. He uses a button but then attaches Javascript to it that calls an MVC action which returns a JSON object. He then parses the object to update the datagrid. I'm not sure how he deals with server-side validation - I think he adds a message property to the JSON object. A sample scenario would be to "Save" a new record that then gets added to the gridview.
The user doesn't see a postback as such, so he uses jQuery to disable the UI whilst the controller action is running.
TBH, it looks pretty cool.
However, the way I'd do it would be to use a Submit button to postback, let the ModelBinder populate a typed model class, parse that in my controller Action method, update the model (and apply any validation against the model), update it with the new record, then send it back to be rendered by the View. Unlike him, I don't return a JSON object, I let the View (and datagrid) bind to the new model data.
Both solutions "work" but we're obviously taking the application down different paths so one of us has to re-work our code... and we don't mind whose has to be done.
What I'd prefer though is that we adopt the "industry-standard" way of doing this. I'm unsure as to whether my WebForms background is influencing the fact that his way just "doesn't feel right", in that a "submit" is meant to submit data to the server.
Any advice at all please - many thanks.
The thing you need to take into consideration is how the application will work if javascript is not available. You should strive to ensure that the basic functionality works without it. This is called progressive enhancement or unobtrusive javascript and is considered a best practice.
http://en.wikipedia.org/wiki/Progressive_enhancement
The way you should do it is to use a form with a real submit button and then hijack that form to use ajax if the User Agent supports it. This is usually pretty trivial to do using the jquery forms plugin. In your action method, you can check to see if the incoming request is an ajax request by checking the Request.IsAjaxRequest property. This is set by MVC automatically on requests that have the X-Requested-With header set to XMLHttpRequest. Then you would return a full view or just some json based on that.
Here's a short screencast demonstrating this: http://www.youtube.com/watch?v=YQsFR1rkgMU&feature=player_embedded
Both solutions are viable, though using submit buttons will make your application more accessible (i.e. JavaScript will not be required in order to use it).
You could also do the both - start with a page that has all the necessary logic using postbacks, and "upgrade" it with nice AJAX-y requests and animations. This way, users with JavaScript will get the eye candy, and the page will gracefully degrade when when a user without JavaScript visits the page, falling back to the postback mechanism.
If I have a search box on my page I clearly do not want the user to input any code that may be dangerous.
However, I have a lot of data entry pages and each one needs to have ValidateInput(false) on the controllers.
I don't want to allow dangerous input, but I also don't want to handle this in each and every controller.
Is there a way that the default, and ugly, error .Net error message can be overwritten, or is there a uniform way of handling this across controllers.
EDIT
I think maybe I didn't ask the question correctly.
For every data entry page I have I have to turn of Input Validation. This becomes somewhat boring and cumbersome. Each time I accept input I need to HTMLEncode and then HTMLDecode later.
Is there a way to do this in one central place and automatically?
About output:
Here's an interesting post.
And another one from Steve Sanderson.
I just read that post some time ago - haven't tried myself.
Give some feedback how it turns out.
About input:
you could try to mess around with model binder and HtmlEncode values it takes.
ASP.NET and MVC don't allow HTML submissions by default. You have to actively enable this. See the ValidateInputAttribute for more information.
Also, even more important than not allowing HTML input is not displaying user submitted HTML when you create output. That's why all of the default generated views use Html.Encode, and why you should, too.
Update in response to edited question
Yes, it's possible (though probably not advisable) to turn off ValidateInput globally. Make a parent controller type, and put
[ValidateInput(false)]
...on the class.
Also, I don't recommend encoding input. If you allow users to input HTML, I'd store that as-is. Your web app might not be the only thing which queries your DB! In terms of filtering out "dangerous" HTML, that's extraordinarily difficult. I'd use a tested, third-party sanitization library.
I'm sort of thinking out loud here, so let me know if I need to clarify...
on ajax heavy sites, when using JsonResult to pass information back to the client, what techniques, patterns, best practices are being used to pass ModelState validation errors back to the client?
I am using xVal and castle validation on my view models, is there some sort of standard to get jquery validate to display errors coming from ajax responses?
I know of no best practices, but I can tell you what I did on a recent project. Basically, I defined an interface for all JSON save results called IJSONValidationResult. This interface consisted of two properties, a bool IsValid indicating if the Save/Action was valid and a List of the errors. The class was than populated with the ModelState validation errors.
Than I used javascript on the client side to parse the JSON result and make the appropriate updates to the page. As an example, if it was valid than redirect from the edit page to the list page showing the saved result, or if there were errors, show them to the user in a previously hidden div.
Nothing too exciting, but it was low overhead and pretty straight forward.