Why unobtrusive validation wont work in asp.net mvc3 without using #Html.BeginForm() - asp.net-mvc-3

To make unobtrusive validation work in asp.net mvc3 you have to use the html helper #Html.BeginForm() as mentioned in this very good post : http://bradwilson.typepad.com/blog/2010/10/mvc3-unobtrusive-validation.html.
Without using the helper unobtrusive validation will not be triggered. I could verify that.
Can you explain me what does the helper #Html.BeginForm() do to allow unobtrusive validation to be triggered when the form is submitted ?
Can you also explain me how could I do that manually (read allow unobtrusive validation without calling the #Html.BeginForm()) ?
Please note that I know I can call unobtrusive validation using $("#myform").valid() but I would like to know the magic behind the helper and how to reproduce it.

When you call BeginForm (see http://j.mp/WrmAyk for the FormExtensionsclass), a new MvcForm object is created.
If you look in the constructor of this class (see http://j.mp/Wrml6F for the MvcForm class) you will see that it creates a new FormContext object: _viewContext.FormContext = new FormContext();.
When an input, textarea or select is rendered using the HTML helper, the following is called: tagBuilder.MergeAttributes(htmlHelper.GetUnobtrusiveValidationAttributes(name, metadata));, which takes care of rendering the validation attributes from the model metadata.
This GetUnobtrusiveValidationAttributes method (see http://j.mp/Wrn4oa for the HtmlHelper class) checks to see if the FormContext is null before rendering attributes:
FormContext formContext = ViewContext.GetFormContextForClientValidation();
if (formContext == null)
{
return results;
}
This is why no validation attributes are rendered unless you are within a form. You can get round this by creating a 'fake' FormContext, like #karaxuna suggests.

Write this in your view and it will work:
ViewContext.FormContext = ViewContext.FormContext ?? new FormContext();
When code is inside #Html.Beginform (in the same view), then html element validation attributes are got from metadata, In other case, it is not.

Related

why we used ajax. BeginForm in mvc instead adding form tags and Html.BeginForm

What is the use of Ajax.BeginForm in MVC4. Why do we use it, when we can just add a form tag directly, does this html helper add some capability or does something which cannot be done with a simple form tag. And also I have found something we can use Html.BeginForm for same purpose, So what is differences between them
""BeginForm()" is an extension method that writes an opening "" tag to the response. "BeginForm()" is an extension method for both HtmlHelper and AjaxHelper classes. It returns an MVCForm object from both HtmlHelper and AjaxHelper class instances so there is not much difference but the AjaxHelper method submits the form asynchronously using JavaScript."
You can also refer to the article for more details:
http://www.c-sharpcorner.com/UploadFile/3d39b4/working-with-html-beginform-and-ajax-beginform-in-mvc-3/
(1)Html.BeginForm will always use RouteTable to detrmine the action attribute value.
(2) provide client side validation
[http://weblogs.asp.net/imranbaloch/asp-net-mvc-client-side-validation-with-dynamic-contents]

Adding validation property attributes in views with Html.EditorFor() methods not inside a Html.BegingForm() method

I have noticed that validation attributes are only added to the elements that were created via Html.EditorFor() helper method and which are inside a Html.BegingForm() method, that respectively creates the "Form" tag and attributes.
Is there any way, besides manually creating the elements and attributes of course to add the required validation attributes to elements created with helper methods and which are not inside the Html.BegingForm() method ?
I need to validate at the client side and don't want to manually either create said attributes or script this behavior explicitly and instead take advantage of the MVC feature that adds said attributes automatically as per metadata on the model for use with the jquery-validate plugin at the client-side.
The unobtrusive validation attributes emitted only if:
the UnobtrusiveJavaScriptEnabled flag is set to true
the ViewContext.FormContext is not null (e.g the Html helper is executed inside a Html.BeginForm block)
So you can manually create a FormContext and assign it to ViewContext.FormContext before using your Html helpers:
#{
ViewContext.FormContext = new FormContext();
}
#Html.TextBoxFor(x => x.SomeProperty)
However you should note that with this approach you lose the from nesting feature of Html.BeginForm so if you want to create a new logical form you need to again create new FormContext() and manage the old context yourself.

MVC3 Force Validation of Hidden Fields

I need to enable the validation of hidden fields using ASP.net MVC3 unobtrusive validation.
The reason behind this is a jquery plugin which hides the original input field to show something fancier. But this disables validation of the field as it becomes hidden.
I tried to use the following code but without success.
$("form").validate({
ignore: ""
});
Thanks
With a hint from this Question I was able to manipulate the options of the unobtrusive validator object.
var validator = $("#myFormId").data('validator');
validator.settings.ignore = "";

Manually bind JQuery validation after Ajax request

I'm requesting an ASP.net MVC view into a live box and the view contains form fields that have been marked up with attributes to be used by JQuery's unobtrusive validators plug-in.
The client script is not however working and my theory is that its because the validation framework is only being triggered on page load which has long since passed by the time the MVC view has been loaded into the live box.
Thus how can I let the validation framework know that it has new form fields to fix up?
Cheers, Ian.
var $form = $("form");
$form.unbind();
$form.data("validator", null);
$.validator.unobtrusive.parse(document);
// Re add validation with changes
$form.validate($form.data("unobtrusiveValidation").options);
You may take a look at the following blog post. And here's another one.
Another option, rather trick, which worked for me. Just add following line in the beginning of the partial view which is being returned by ajax call
this.ViewContext.FormContext = new FormContext();
Reference
For some reason I had to combine bjan and dfortun's answers...
So I put this in my view:
#{
this.ViewContext.FormContext = new FormContext();
}
And this execute this after the ajax call finishes:
var form = $("#EnrollmentForm");
form.unbind();
form.data("validator", null);
$.validator.unobtrusive.parse(document);
form.validate(form.data("unobtrusiveValidation").options);
I had a similar issue. I had a form that was using Ajax requests to re-display a part of the form with different form fields. I used unobtrusive validation by manually doing it on the client side using the
#Html.TextBoxFor
for my text boxes. For some reason the validation works when attempting to submit with invalid fields (i.e., the text boxes get outlined in red and the appropriate error messages display with the content I put in the
data_val_required
attribute, for example.
However, after I click a button that makes an Ajax request to modify the form with different fields and then submit again, only the red outline on the invalid fields display, but no error messages are rendered.
bjan's trick worked for me, but I still can't see what was causing the issue. All the HTML necessary to carry out the client-side validation was there I just can't figure out why the error message attribute values wouldn't display.
All I can think of is that the jQuery validation code doesn't make a second attempt to check the form fields after a submit was made.

Enable/Disbale Validation in ASP .net MVC 3

I have a HTML form and within that form I have a DropDownList and a Button that can post to my action method. I want to disable the validation when the post is made by my DropDownList and enable it when it is made by the button.
In my action method I can differentiate, which one is making the post but I can not disable the validation.
I tried to set ValidateRequest = false but it didn't work. I don't want to use Ajax call at this stage.
Thank you
Try this:
Html.DropDownList(..., ..., new { disableValidation = "true" })

Resources