ASP.NET MVC 2 - Some validation errors are not appearing - validation

I'm testing my view/edit model's Data Annotations, and some of the errors aren't showing up. They're all property-level, but they're not showing up as either property-level or model-level. They're simply not showing up at all.
My view/edit model:
public class AdminGameEditModel
{
[Required]
public int GameID { get; set; }
[Required(ErrorMessage="A game must have a title")]
[DisplayFormat(ConvertEmptyStringToNull=false)]
public string GameTitle { get; set; }
[Required(ErrorMessage="A short URL must be supplied")]
[DisplayFormat(ConvertEmptyStringToNull=false)]
public string Slug { get; set; }
[Required(ErrorMessage="A box art image must be supplied")]
public HttpPostedFileBase BoxArt { get; set; }
[Required(ErrorMessage="A large image for the index page is required")]
public HttpPostedFileBase IndexImage { get; set; }
[Required(ErrorMessage="A game must have a review")]
[DisplayFormat(ConvertEmptyStringToNull=false)]
public string ReviewText { get; set; }
[Required(ErrorMessage="A game must have a score")]
public int ReviewScore { get; set; }
[Required(ErrorMessage="A game must have at least one Pro listed")]
[DisplayFormat(ConvertEmptyStringToNull=false)]
public string[] Pros { get; set; }
[Required(ErrorMessage="A game must have at least one Con listed")]
[DisplayFormat(ConvertEmptyStringToNull=false)]
public string[] Cons { get; set; }
[Required(ErrorMessage="A game must belong to a genre")]
public int GenreID { get; set; }
[Required(ErrorMessage="A game must be associated with at least one platform")]
public int[] PlatformIDs { get; set; }
}
The properties whose validation doesn't seem to be working properly are Pros, Cons, and GenreID. Here's how I'm trying to invoke them in my view:
<p>
<%: Html.Label("Genre") %>
<%: Html.ValidationMessageFor(model => Model.GameData.GenreID) %>
<%: Html.DropDownListFor(m => Model.GameData.GenreID, new SelectList(Model.AllGenres, "GenreID", "Name", Model.GameData.GenreID)) %>
</p>
<p>
<%: Html.LabelFor(model => Model.GameData.Pros) %><br />
<% for (var i = 0; i < 5; ++i)
{ %>
<input type="text" name="GameData.Pros" value="<%: (Model.GameData.Pros[i] != null && String.IsNullOrEmpty(Model.GameData.Pros[i])) ? "" : Model.GameData.Pros[i] %>" /><br />
<% } %>
<%: Html.ValidationMessageFor(model => Model.GameData.Pros) %>
</p>
<p>
<%: Html.LabelFor(model => Model.GameData.Cons) %><br />
<% for (var i = 0; i < 5; ++i)
{ %>
<input type="text" name="GameData.Cons" value="<%: (Model.GameData.Cons[i] != null && String.IsNullOrEmpty(Model.GameData.Cons[i])) ? "" : Model.GameData.Cons[i] %>" /><br />
<% } %>
<%: Html.ValidationMessageFor(model => Model.GameData.Cons) %>
</p>
The rest all show up fine. I'm stumped as to why those three aren't appearing. I don't see anything that jumps out to me as the cause. I'm using the default model binder and validation service.
Any ideas?

Well, for starters.. your input fields have no id's. Model validation doesn't work with names, only id's. But that's only part of the problem. The Model Binder is unlikely to be able to bind to arrays because arrays are immutable, this makes it hard to do iterative assignment to them. You're going to have to rethink this part of your application.
Second, your DropDownList has no default value. It will, in most cases just select the first item so there is no way for it to not be valid.
You may find this article interesting.

Related

How to validate textbox in MVC3 that must contain string started with characters "PR"

i am very much new to MVC3 and working with MVC3 razor application. I need to validate a textbox on View in such a way that, the textbox will accept only those strings which are starting with characters "PR" and 4th character of that string must be "2". It would be great if anybody helps me. Thanks in advance
Well you need regex. I'm not exactly sure what the regex would be and what your string contains. But if you need to have 2 matches in there, you could split it and use 2 textboxes and join the values on post.
ViewModel:
public class MyViewModel
{
[RegularExpression("^PR[A-Za-z0-9]", ErrorMessage= "Invalid Text1")]
public string MyText1 { get; set; }
[RegularExpression("^2[A-Za-z0-9]", ErrorMessage= "Invalid Text2")]
public string MyText2 { get; set; }
}
Warning, this regex may be faulty. I invite others to edit/post comments and i can update it with correct regex
View:
#model MyProject.Models.MyViewModel
#using (Html.BeginForm())
{
#Html.TextBoxFor(m => m.MyText1)
#Html.TextBoxFor(m => m.MyText2)
<button type="submit">Submit</button>
}
Hope this helps
Model
public class RegisterModel
{
public int ID { get; set; }
[RegularExpression(#"^PR[a-zA-Z0-9]2([a-zA-Z0-9]*)$", ErrorMessage = "Please enter valid Name.")]
[Required(ErrorMessage = "Name is required.")]
public string Name { get; set; }
}
View
#using (Html.BeginForm("DYmanicControllerPage", "Test", FormMethod.Post, new { id = "FrmIndex" }))
{
<div>
#Html.LabelFor(m => m.Name)
#Html.TextBoxFor(m => m.Name)
#Html.ValidationMessageFor(m => m.Name)
</div>
}

MVC3 Navigation Property Attributes and Client Side Validation

I am making my first tentative steps into MVC3 and have come across an issue with the translation of navigation properties within a model to a view. It seems that in the view navigational properties do not allow client side validation nor is the "Display" label attribute picked up.
I have the following simple model:
public class Entity
{
[Key,
ScaffoldColumn(false)]
public int Entity_Id { get; set; }
[Display(Name = "Entity Name"),
Required(ErrorMessage = "Please enter the entity name."),
StringLength(150, ErrorMessage = "Please ensure that the entity name is under 150 characters.")]
public string Entity_Nm { get; set; }
[Display(Name = "Entity Type"),
Required(ErrorMessage="Please select the entity type"),
ForeignKey("EntityType")]
public int EntityType_Id { get; set; }
public virtual EntityType EntityType { get; set; }
}
Which references this model:
public class EntityType
{
[Key]
public int EntityType_Id { get; set; }
[Display(Name = "Entity Name"), Required(ErrorMessage="Please enter the entity type name.")]
public string EntityType_Nm { get; set; }
}
When I create a controller with read/write actions and views for this model I get the following create form:
<fieldset>
<legend>Entity</legend>
<div class="editor-label">
#Html.LabelFor(model => model.Entity_Nm)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Entity_Nm)
#Html.ValidationMessageFor(model => model.Entity_Nm)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.EntityType_Id, "EntityType")
</div>
<div class="editor-field">
#Html.DropDownList("EntityType_Id", String.Empty)
#Html.ValidationMessageFor(model => model.EntityType_Id)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
This is fine apart from the label for the Entity Type drop down, for some reason it is not picking up the "Display" attribute of the navigation property within the model (note the lack of a space). Also client side validation is not enabled for the dropdown list (server side validation works without issue) despite decorating the property with a "Required" attribute. Client side validation works on the other fields. Please note that all the required .js script files have been included and I have also added the relevant enable validation keys to the web.config.
Any ideas what I am missing here? Thanks one and all.
for DropDownList Display issue just try below
#Html.LabelFor(model => model.EntityType_Id)

Model CheckBoxFor Properties being posted twice Asp Net MVC 3

So I have a partial view...
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<NewsletterUnsubscribe_MVC3v2.Models.IntegraRecord>" %>
<% if (!String.IsNullOrEmpty(Model.ErrorMessage))
{%>
<div class="input-validation-error">
<%:Model.ErrorMessage %>
</div>
<% }
else
{%>
<% using (Html.BeginForm())
{%>
<%:Html.ValidationSummary(true)%>
<fieldset>
<legend>IntegraRecord</legend>
<div class="editor-field">
<%:Html.LabelFor(m => m.EmailAddress)%>: <strong><%:Model.EmailAddress%></strong>
</div>
<%:Html.HiddenFor(m=>m.EmailAddress) %>
<div class="editor-field">
Unsubscribe from Area mailings: <%:Html.CheckBoxFor(m => m.AreaUnsubscribe)%>
</div>
<div class="editor-field">
Unsubscribe from Monthly newsletters: <%:Html.CheckBoxFor(m => m.MonthlyUnsubscribe)%>
</div>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
<% }
}%>
When I hit submit and look what's in the posted data I see
EmailAddress:someone#somewhere.co.uk
AreaUnsubscribe:true
AreaUnsubscribe:false
MonthlyUnsubscribe:true
MonthlyUnsubscribe:false
As a result TryUpdateModel returns true but doesn't populate any fields
This gets posted to the controller...
[HttpPost]
public ActionResult GetRecord(IntegraRecord model)
{
if (TryUpdateModel(model))
{
try
{
BusinessLayer.UpdateEmailAddress(model);
}
catch (ArgumentException)
{
return View("Error", ViewBag.Message = "Could Not Update Email Address.");
}
}
return PartialView("GetRecord", model);
}
Any help massively appreciated...
Update: So following the clarification below (Thanks!)
I'm not using a custom model binder so I guess I'm missing some other convention too...
Here's my model...
public class IntegraRecord
{
private const string EmailRegex = #"[snip]";
[Required(ErrorMessage = "Email Address is required")]
[RegularExpression(EmailRegex, ErrorMessage = "This does not appear to be an email address")]
public string EmailAddress;
public bool AreaUnsubscribe;
public bool MonthlyUnsubscribe;
public string ErrorMessage;
public IntegraRecord()
{
}
public IntegraRecord(string email, bool area, bool monthly)
{
EmailAddress = email;
AreaUnsubscribe = area;
MonthlyUnsubscribe = monthly;
}
}
That's how MVC handles checkboxes: asp.net mvc: why is Html.CheckBox generating an additional hidden input (and many other places)
The problem is onthe server side (default model binder is aware of that and doesn't have a problem). Are you using custom model binder?

Html.EditorForModel and Hiding element from Edit

I'm using the following code to render an editor for my model using ASP.NET MVC 3, it works perfect, except for I don't want the user to see or edit the "Id" field in my object.
<% using (Html.BeginForm())
{ %>
<%: Html.ValidationSummary(true, "Your input has errors, please correct and try again") %>
<%: Html.EditorForModel(Model)%>
<input type="submit" value="Update" />
<% } %>
In my model for the ID Field I have the following
[Display(AutoGenerateField = false)]
public int Id{ get; private set; }
Which granted is what I thought would work based on the description of the "AutoGenerateField" parameter. However this isn't working. I don't want to have to build the whole editor just for this one little oddity....
Use [ScaffoldColumn(false)] to hide fields
You could use the [HiddenInput] attribute:
[HiddenInput(DisplayValue = false)]
[Display(AutoGenerateField = false)]
public int Id { get; private set; }

client side validation for asp.net mvc dropdown?

i just wanted to know how to enable client side validations for dropdowns in asp.net mvc 2.
The scenario would be that the dropdown will contain a "Select" item and the list of other items..,The user should select other items... the validation should fire when the user does not select the other items
public class FacilityBulletinModel
{
[DisplayName("Select a Facility")]
public List<SelectListItem> ListFacility { get; set; }
[DisplayName("Facility Bulletin")]
[Required(ErrorMessage = "Please create a Bulletin")]
public string FacilityBulletin { get; set; }
[DisplayName("Active")]
public bool Active { get; set; }
[HiddenInput(DisplayValue = false)]
public int SiteId { get;set;}
}
in my view
Select Facility <span class="err">*</span><br />
<%=Html.DropDownListFor(model => model.ListFacility, null, new {onChange="updateSiteId()" })%>
<span class="err"> <%= Html.ValidationMessageFor(model => model.ListFacility) %></span>
First, if a dropdown is required, add the [Required] attribute to your model property.
Then, enable client side validation somewhere at the top of your view:
<% Html.EnableClientValidation() %>
Then just add a validation message:
<div class="inputField">
<%= Html.LabelFor(model => model.property)%>
<%= Html.DropDownListFor(model => model.property, (SelectList)ViewData["myselelectlist"])%>
<%= Html.ValidationMessageFor(model => model.property)%>
</div>
(this requries MicrosoftMvcValidation.js to be loaded)

Resources