How to specify that a Search Input field is required - asp.net-mvc

I am working with an asp.net mvc web application and i have a text input field to enter a search criteria, but my question is how i can define that this field is required incase the user click on the search button. i was thinking of manually adding the following data dash attributes, to simulate how the [Required] model data annotation works .
<input name="selectedUserNames" type="text" data-val="true" data-val-required= "Please enter a value." data-autocomplete-source= "#Url.Action("AutoComplete", "SecurityGroup")" />
<span class="field-validation-valid" data-valmsg-for="selectedUserNames" data-valmsg-replace="true"></span>
<input type="submit" value="Seach" />

What you are doing is not a clean solution, and it only works on the client side. You should create a SearchViewModel like below and pass it to your View:
public class SearchViewModel
{
[Required]
public string Search { get; set; }
}
And, in your View:
#Html.TextBoxFor(model => model.Search)
#Html.ValidationMessageFor(model => model.Search)

as noted in previous answer, enabling only client side validation is not a complete solution. what if the client has disable javascript on their browser? then your validation want fire.
best option you have is to use DataAnnotation [Required] attribute. In your view enable client side validation.
If the client has disable javascript on browser server side validation will fire.

Related

ASP.NET MVC Encoding Issue

I have an ASP.NET MVC app. My app is passing a name to/from the database. I've recently discovered a bug associated with ampersands (&).
In my database, I see the name "A & W".
I am displaying this value in my UI using the following:
<input id="Name" name="Name" value="#Html.Raw(Model.Name)" />
When I view the source, I can see that the following HTML gets rendered in the browser.
<input id="Name" name="Name" value="A & W" />
So far, so good. However, when I click save, and I set a breakpoint in my controller action, I can see the Name property on my Model is now "A & W". What's worse is, everytime I save it, additional amp values get added.
How do I remedy this?
Thanks!
I had a similar problem, so I used the AllowHtml attribute on my property in my model.
[AllowHtml]
public string Name { get; set; }
If you aren't using Code First, you can apply this attribute on top of your action also:
[HttpPost]
[AllowHtml]
[ValidateAntiForgeryToken]
public ActionResult Modify(ModelClass model) {}

MVC #Html.CheckboxFor submits true,false on form submission

I am using MVC 5 with EF Code First and have a View model that contains a bool:
public bool MyCheckbox { get; set; }
I initialize this in my View's get:
model.MyCheckbox = true;
In the View:
#Html.CheckBoxFor(m => m.MyCheckbox)
Which get rendered as:
<input checked="checked" data-val="true" data-val-required="The field is required." id="MyCheckbox" name="MyCheckbox" type="checkbox" value="true" />
<input name="MyCheckbox" type="hidden" value="false" />
One of my Buttons on the View triggers an Ajax POST to the Controller where I want to look at the checkbox value:
bool bValue = Request["MyCheckbox"] == "true";
But the value of Request["MyCheckbox"] is "true,false" due to the extra hidden field with name="MyCheckbox".
How do I view the value of this checkbox in the controller with Request["..."] and make sense of it (either true or false)?
I also have another bool member in the View model and I use it in a hidden field intentionally. In the model:
bool MyHiddenBool { get; set; }
In the Controller Get:
model.MyHiddenBool = true;
In the View:
#Html.HiddenFor(x => x.MyHiddenBool)
In the Controller (via Ajax POST):
bool AnotherBool = Request["MyHiddenBool"] == "true";
But the value of Request["MyHiddenBool"] is either "True" or "False" instead of "true" and "false".
What gives with this inconsistency and how can I reliably see the values of these two methods of bools in my Views?
The problem is how you are consuming the form request variable.
In ASP.NET MVC there's probably never a good reason to use Request.Form or it's variants to consume your request data. You need to make a model or put in an argument for the action.
[HttpPost]
public ActionResult PostedForm(bool myHiddenBool)
{
//Frameworks model binder will extract the form field into your variable based on the name
}
The following copied from this answer.
This isn't a bug, and is in fact the same approach that both Ruby on
Rails and MonoRail use.
When you submit a form with a checkbox, the value is only posted if
the checkbox is checked. So, if you leave the checkbox unchecked then
nothing will be sent to the server when in many situations you would
want false to be sent instead. As the hidden input has the same name
as the checkbox, then if the checkbox is unchecked you'll still get a
'false' sent to the server.
When the checkbox is checked, the ModelBinder will automatically take
care of extracting the 'true' from the 'true,false'

Html.HiddenFor handles string and int differently

My model:
public class VerifyModel
{
public string PIN { get; set; }
public int Attempts { get; set; }
}
My view:
#Html.HiddenFor(m => m.PIN)
#Html.HiddenFor(m => m.Attempts)
On entry into the view, I inspect Model.PIN and Model.Attempts and they contain the correct values passed from the controller, where Attempts is non-zero. The Html rendered is however:
<input id="PIN" name="PIN" type="hidden" value="xxxx" />
<input data-val="true" value="0" data-val-number="The field Attempts must be a number." data-val-required="The Attempts field is required." id="Attempts" name="Attempts" type="hidden"/>
The value of Attempts is always 0! And I did not specify anywhere that the Attempts field is mandatory.
How do I solve the problem of int properties in the model?
If I've understood your question correctly, you're having problems with Attempts not incrementing after the form is posted back with an incorrect PIN. If that assumption is correct then you're experiencing this problem because of the way ModelState works.
The short answer to the problem is simply to call ModelState.Remove from your action:
[HttpPost]
public ActionResult YourAction(VerifyModel model)
{
ModelState.Remove("Attempts");
model.Attempts++;
return View(model);
}
If you'd like a full explanation of why this is the case, see ASP.NET MVC’s Html Helpers Render the Wrong Value!. Excerpt:
Why?
ASP.NET MVC assumes that if you’re rendering a View in response to an HTTP POST, and you’re using the Html Helpers, then you are most likely to be redisplaying a form that has failed validation. Therefore, the Html Helpers actually check in ModelState for the value to display in a field before they look in the Model. This enables them to redisplay erroneous data that was entered by the user, and a matching error message if needed.

Exclude <input type='file'> from ViewModel

I have the following file input tag in the "Create" View:
<input type="file" id="RequestFile" name="RequestFile"/>
#Html.ValidationMessage("RequestFile")
The ViewModel contains this corresponding property:
[Required(ErrorMessage="Please select a file")]
public HttpPostedFileBase RequestFile { get; set; }
This works fine in the "Create" View, but in the "Edit" View, I get ModelState.Isvalid as false. Using the same ViewModel I would like to exclude this field from validations because I would not want to upload the file again.
I tried simply disabling the input tag like this:
<input type="file" id="RequestFile" name="RequestFile" disabled/>
This has a disabled input control but the Validation still fired.
Also applying the BindAttribute in the Controller did not work (see this Question)
Ideally (I know it sounds unlikely), if there is a server-side solution to this, please post your thoughts. If there is a small client-side trick, please let me know!
The best ways are remove the property altogether, and always access it directly from the form collection (and manually validate it) or manually remove the model state error using the property name (as #cheesemacfly has in his comment, ModelState.Remove("RequestFile")). The latter makes it very easy to fix then.
You could use form.onsubmit to check to see it document.getElementById("RequestFile").value is not null/empty and cancel the submit if it is.
something like
<form onsubmit="if(!document.getElementById('RequestFile').value){alert('Please select a file.');return false;}" >
<input type="file" id="RequestFile" name="RequestFile" />
<input type="submit"/>
</form>
return false cancels the submission.
http://jsfiddle.net/Cg7HY/1/
or put it in the click event of the submit button itself
http://jsfiddle.net/Cg7HY/3/

jQuery Mobile and Unobtrusive Validation

I'm creating a jQuery Mobile (Alpha 3) based ASP.NET MVC 3 application utilizing the unobtrusive validation that comes with MVC3. When a page is accessed directly (no hash in the Url), validation works perfectly. However, when you navigate to the page, jQuery Mobile uses Ajax Navigation to dynamically load it (displaying the hash in the Url) and validation stops working.
Here is a sample of the code in use:
Model:
[Required(ErrorMessage = "Missing value")]
[DisplayName("Property Display Name")]
public int? PropertyName { get; set; }
View (Razor):
#Html.LabelFor(model => model.PropertyName)
#Html.TextBoxFor(model => model.PropertyName)
#Html.ValidationMessageFor(model => model.PropertyName)
Generated HTML:
<label for="PropertyName">Property Display Name</label>
<input data-val="true" data-val-number="The field Property Display Name must be a number." data-val-required="Missing value" id="PropertyName" name="PropertyName" type="text" value="" />
<span class="field-validation-valid" data-valmsg-for="PropertyName" data-valmsg-replace="true"></span>
It is possible that other pages have been loaded previously and the HTML elements no longer have unique Ids. Other than rolling my own Html Helper class to generate the HTML for the Label, TextBox, and ValidationMessage, is there any way to handle this scenario?
I've been struggling a bit with this same issue, but #Zote pointed me in the right direction.
parse() is the way to go, but make sure to pass in a selector ie:
jQuery.validator.unobtrusive.parse("form")
or
jQuery.validator.unobtrusive.parse(document)
The best way of hooking this up is probably through JQMspageshow event. This would then be triggered after each new page transition, like so, You may also prefer to do this before jqm has done it's magic on the page as well by using the pagebeforeshow event
$('div').live('pageshow',function(event){
jQuery.validator.unobtrusive.parse(".ui-page-active form");
});
By using the .ui-page-active, you narrow your search down to the currently active page.
Did you call jQuery.validator.unobtrusive.parse() after loaded new content?
Read this post at Brad Wilson's blog.
I solved the same problem I encountered, my answer is posted here -
Hash navigation problem while using jquery mobile with asp.net mvc2

Resources