Difference between 'Html.Validate' and 'Html.ValidateFor' - asp.net-mvc

Why do we use .Validate and .Validatefor in validation?
I am using that, but I am not getting any error message in the UI.
Code
<div>
#{Html.BeginForm();}
#Html.TextBoxFor(x => x.LastName, new { id = "txtLastName" })
#{Html.Validate("LastName");}
#{Html.ValidateFor(x=>x.LastName);}
<input type="submit" id="btnSubmit" value="Submit" />
#{Html.EndForm();}
</div>

This behavior is intentional. Both these helpers just register corresponding parameters for client-side validation, without actually showing any message should the validation fail. However this message can still be displayed in a ValidationSummary.
If you want to show the message specific to the field/parameter, you should use ValidationMessage or ValidationMessageFor instead:
#Html.ValidationMessage("LastName")
#Html.ValidationMessageFor(x=>x.LastName)

If there are situations where you don't actually want a validation message to visually appear for each field (i.e. by using Html.ValidationMessage), but would rather allow a summary to be the sole source of validation error messages (i.e. by using Html.ValidationSummary), you still need some way to "trigger" the validation to occur for the specific fields you want it to. This can be achieved by using the Html.Validate/Html.ValidateFor<> methods within your view. Those helpers won't render anything, but will simply register the specified field for client-side validation.
See this post for answer How does validation in ASP.NET MVC 2 actually work?

Related

Adobe DTM: Event based rule to track form submission

I am trying to track form submission for a form using event based rule in DTM. I know that the ideal way to do it is to do via direct call rule but need to track the form fields as well through a data element and then into an eVar.
The form code looks something like this on the page:
<div style='display:none'>
<div id="popupform">
<div class="form_container">
<img src="/images/New-Offer-Pop-Up-Without-form_18-Jan-16.jpg" style="width: 100%;">
<form class="offerform" accept-charset="UTF-8" action="/site/sendtohs">
<div class="formrow"><input type="text" name="popup_fullname" class="new-input1 required" placeholder="Name" /></div>
<div class="formrow"><input type="email" name="popup_email" class="new-input1 required" placeholder="Email" /></div>
<div class="formrow"><input type="number" name="popup_phone" class="new-input1 required" placeholder="Mobile"
minlength="10" maxlength="15" /></div>
<input type="hidden" name="popup_url" value="/" /></br>
<p align="right"><input class="tbn newtbn" type="submit" name="submit" value="Submit" /></p>
</form>
</div>
<div class="offerform_success" style="display: none">
<img src="/images/Thank-you-pop-up-new-xyz.jpg" style="height: 440px; width: 100%; position: absolute;width: 99%;">
</div>
</div>
</div>
The even based rule in DTM is :
DTM Rule
The event fires when I click on the Submit button but the rule does not validates if the form fields have been filled or not. Any hints how can I add validation to the form submit event within DTM.
Targeting the form
Firstly, based on your screenshot vs. posted code, your event will not trigger because the form tag does not have an id attribute of "popupform" (or any id attribute at all) (You do have that as an id in a parent div, but that's not what you are targeting). So, you will need to remove that.
If you only want to target the form if it's within a div, then you will need to add it as a Rule Condition. Under Rule Conditions > Criteria, choose "Data > Custom", and click Add Criteria.
In the code box, add the following:
if ($(this).parents('#popupform').length)
return true;
return false;
Note: I'm using jQuery syntax here for brevity and easy cross-browser compatibility. The overall goal is this references the targeted form, and you want to check that it is within an html element with the popupform id. The jQuery above traverses up the form's ancestor chain to look for it. If it finds it, we return true. Otherwise we return false. Ultimately, custom rule conditions should return true if you want it to pass, or false if not. Also note that if you have multiple rule conditions (which you will; see below), all conditions must return true in order for the rule to trigger. If your site does not use jQuery or you do not want to use jQuery for this, then you will need to write your own code following the above concept.
Validating the form fields
Before I get into this, one thing I should note is in general you should not rely on client-side form validation for your forms. It is super easy to disable/get around it. You should be doing form validation with server-side code when the form is submitted, and then pop whatever you need to pop (form complete tracking or w/e) after it has been server-side validated.
Maybe you already have server-side validation in place but for whatever reason you can't control popping a dtm rule after validation, and this is your next best thing. Well hopefully the only thing you are doing is popping tracking and not using the dtm rule for actual site functionality, but even then, just want you to be aware that this is a "lesser evil" solution, not a "good" solution.
Having said that, you can again turn to a custom condition to make sure all the form fields are filled out. Here is a quick and dirty custom rule condition to demonstrate. Again, under Rule Conditions > Criteria, choose "Data > Custom", and click Add Criteria (so you will now have another custom code box). Add the following:
var isFieldsFilled=true;
$.each($(this).serializeArray(),function(i,v) {
if (!v.value||v.value=='')
isFieldsFilled=false;
});
return isFieldsFilled;
This code again uses jQuery to grab the form fields of the targeted form and loops through them and sets a flag to false if one is found not to have a value. Again, this is kind of quick and dirty and will work based on your current form example, but you may need to expand upon it in practice.

How to display a name after successful remote validation?

My business web application will have a lot of input controls where the user is expected to enter some kind of code (Country, Zip, Employee ID, etc.).
I'm using RemoteAttribute to validate code entries against my database to ensure that users entered the correct code.
The thing is, my standard feature should be to display a name of entered code if the remote validation is successful or error if the validation is not successful.
I'm not sure how to do this.
The obvious answer is to send Name property along with true value in Json object which jquery unobtrusive validation requires. The cshtml could look something like this:
#Html.LabelFor(m => m.Country)
#Html.EditorFor(m => m.Country, new { data-codename-label="lbnCountry" })
<label ID="lbnCountry"></label>
I'm not sure how to implement such an idea though. Any help is appreciated.
Take a look at this answer which should work for you as well.
Do something on success response for remote validation in mvc
If in that example you choose not to send your value through the custom response header, you can always modify the javascript to do an ajax call to an action/webapi that will return the value in question after a successful validation.

use textbox correctly without textboxfor helper in asp.net mvc?

i don't like auto-generated code so i made a decision to never use Asp.net MVC's Html Helpers, but i face a problem when it comes to save the value of an input after validation failed, so the value is saved when i use
#Html.TextBoxFor(m=>m.Name)
but it doesn't save the value when i write
<input type="text" name="Name"/>
so how can i have the same thing without using TextBoxFor Helper, and what does this helper do, that i haven't
i don't like auto-generated code so i made a decision to never use Asp.net MVC's Html Helpers
You are going to have a hell hard time doing ASP.NET MVC development if you do not use helpers and I am afraid that you will not get very far. You will struggle not only with things like setting values for input fields but also emitting HTML5 data-* attributes on your input fields for things like unobtrusive client side validation, all things that are automatically handled by HTML helpers.
You could always perform the following pornography in your view if you find that more readable:
<input type="text" name="Name" value="#Html.Raw(HttpUtility.HtmlAttributeEncode(Model != null ? Model.Name : ""))" />
But I don't know why I kinda prefer writing #Html.TextBoxFor(m => m.Name). I don't know, maybe it's just a matter of personal preference.
But to answer your question, you can do ASP.NET MVC without helpers. It's just that you might find that a pretty disagreeable experience.

Why doesn't TextBoxFor include validation elements if called twice for the same model property?

Simple question... Here is an example of some razor code:
#Html.TextBoxFor(c => c.RevisedEstimate)
#Html.TextBoxFor(c => c.RevisedEstimate)
Here is how this renders:
<input data-val="true" data-val-number="The field Revised Estimate must be a number." id="RevisedEstimate" name="RevisedEstimate" type="text" value="0" />
<input id="RevisedEstimate" name="RevisedEstimate" type="text" value="0" />
The obvious question you ask is, "Why are you doing that?". The razor view is actually building client side detail-row templates that are used in KendoUI grids. There are two similar grids and we use the same viewmodel server side. We actually do provide the id element for the template so each field in each row ends up with a unique id.
Why does the second input element not have the data-val and data-val-number elements?
Off the top of my head knowing what the JS does in the background, it seems to do this to prevent conflicts. The JS looks for the elements with the data- attributes to do it's validation, along with other functions, so it could possibly pick the wrong one if there are multiple instances of it.
since we were generating HTML for use in a client side template what we did was just create a variable to hold the HTML generated by the helper, and then render out that code in the Views..
Something like:
#{
var revisedEstimateInput = Html.TextBoxFor(c => c.RevisedEstimate)
}
Then later in the view:
#(revisedEstimateInput)
...in as many places as needed. This way the validation and other metadata attributes were in place in our client templates and all the kenodUI validation worked correctly.

How to stop ASP.NET MVC ajax form POST responses from having their form fields reset?

I am using an AJAX form post to send some form fields to the server, where the data will be updated in the database, and is massaged in the process, so the data may change a bit on the server side. The response of this controller's action is a partial that updates the form field's HTML so that the values of those fields include the new massaged values.
The trouble is, apparently some MVC .js must be executing on the returned partial's HTML to change the value of the text fields back to their originally posted values, so that the massaged values never show up.
I can see how this might be useful in some scenarios, but it's defeating my scenario. How do I suppress this behavior?
EDIT
I've discovered that if in my partial I replace this:
<%= Html.TextBox("FirstName", Model.FirstName) %>
with this:
<input name="FirstName" value="<%= Html.Encode(Model.FirstName) %>" />
that the value in the form field updates as I would expect. So it seems there's some magical side-effects of Html.TextBox that I don't yet understand.
I don't think there's any random javascript being executed. MVC doesn't rely on javascript, and certainly wouldn't be injecting it into your pages.
More likely the issue is that your ModelStateDictionary is holding the original values. Values that exist simply in the form post but that are not applied to the model are not going to show up. See this thread for some helpful pointers.

Resources