drop down list validation message mvc - validation

In my viewModel I have
public string Addressline1 { get; set; }
public List<SelectListItem> StateList
{
get
{
return State.GetAllStates().Select(state => new SelectListItem { Selected = false, Text = state.Value, Value = state.Value }).ToList();
}
}
In the view I have
#Html.DropDownListFor(model => model.StateCode, Model.StateList, "select")
when AddressLine1 is entered, then the statelist DropDownList selection is Required.How do I validate and show an error message when no state is selected in the Drop down list other than default "select" value?

Decorate your StateCode property with the [Required] attribute:
[Required(ErrorMessage = "Please select a state")]
public string StateCode { get; set; }
public IEnumerable<SelectListItem> StateList
{
get
{
return State
.GetAllStates()
.Select(state => new SelectListItem
{
Text = state.Value,
Value = state.Value
})
.ToList();
}
}
and then you could add a corresponding validation error message:
#Html.DropDownListFor(model => model.StateCode, Model.StateList, "select")
#Html.ValidationMessageFor(model => model.StateCode)
UPDATE:
Alright it seems that you want to conditionally validate this StateCode property depending on some other property on your view model. Now that's an entirely different story and you should have explained this in your original question. Anyway, one possibility is to write a custom validation attribute:
public class RequiredIfPropertyNotEmptyAttribute : ValidationAttribute
{
public string OtherProperty { get; private set; }
public RequiredIfPropertyNotEmptyAttribute(string otherProperty)
{
if (otherProperty == null)
{
throw new ArgumentNullException("otherProperty");
}
OtherProperty = otherProperty;
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
var property = validationContext.ObjectType.GetProperty(OtherProperty);
if (property == null)
{
return new ValidationResult(string.Format(CultureInfo.CurrentCulture, "{0} is an unknown property", new object[]
{
OtherProperty
}));
}
var otherPropertyValue = property.GetValue(validationContext.ObjectInstance, null) as string;
if (string.IsNullOrEmpty(otherPropertyValue))
{
return null;
}
if (string.IsNullOrEmpty(value as string))
{
return new ValidationResult(FormatErrorMessage(validationContext.DisplayName));
}
return null;
}
}
and now decorate your StateCode property with this attribute, like so:
public string AddressLine1 { get; set; }
[RequiredIfPropertyNotEmpty("AddressLine1", ErrorMessage = "Please select a state")]
public string StateCode { get; set; }
Now assuming you have the following form:
#using (Html.BeginForm())
{
<div>
#Html.LabelFor(x => x.AddressLine1)
#Html.EditorFor(x => x.AddressLine1)
</div>
<div>
#Html.LabelFor(x => x.StateCode)
#Html.DropDownListFor(x => x.StateCode, Model.States, "-- state --")
#Html.ValidationMessageFor(x => x.StateCode)
</div>
<input type="submit" value="OK" />
}
the StateCode dropdown will be required only if the user entered a value into the AddressLine1 field.

Related

validate dropdown in mvc5

I am having trouble in attempting to validate that a value has been chosen from a dropdown as follows:
Please Select Type
Keypad
Bill Pay
I have added the following details as part of my model:
[Required]
[StringLength(20, MinimumLength = 10)]
public string AccountType { get; set; }
When I post the form it is not highlighting the account type as not being filled out correctly. Any ideas why? I thought that the minimum length would have caught this
I will show validation for country below.
Model:
public class CountryModel
{
[Required(ErrorMessage="Country Required.")]
public int SelectedCountryId { get; set; }
public System.Web.Mvc.SelectList Countries { get; set; }
}
Controller:
public ActionResult Index(CountryModel model)
{
if (model.Countries == null)
{
model.Countries = new SelectList(new List<SelectListItem>()
{
new SelectListItem() { Text= "India", Value = "1" },
new SelectListItem() { Text= "Australia", Value = "2"}
},"Value","Text");
}
return View(model);
}
My View:
#model MVCControls.Models.CountryModel
#{
ViewBag.Title = "Index";
}
<h2>Dropdownlist Validation</h2>
#using (Html.BeginForm())
{
#Html.ValidationSummary()
#Html.Label("Country")
#Html.DropDownListFor(c => c.SelectedCountryId,Model.Countries, "..Select..")
#Html.ValidationMessage("Country is required.");
<input type="submit" name="name" value="Submit" />
}
Hope this helps

SelectList in MVC3

I have a MVC3 page that has to dropdownList contains Sex(male,female) and Role(admin,Operator), in RegisterViewModel I have done like this :
public List<SelectListItem> SelectedItemForSex { get; set; }
public List<SelectListItem> SelectedItemForRole { get; set; }
public string SearchText { get; set; }
public string SelectedValue { get; set; }
//public string SelectedValueForRole { get; set; }
public static RegisterViewModel Get()
{
var model = new RegisterViewModel { SelectedItemForSex = new List<SelectListItem>() };
model.SelectedItemForSex.Add(new SelectListItem() { Text = "Male", Value = "1" });
model.SelectedItemForSex.Add(new SelectListItem() { Text = "Femle", Value = "2" });
model.SelectedItemForRole.Add(new SelectListItem() {Text = "Administrator", Value = "1"});
model.SelectedItemForRole.Add(new SelectListItem() {Text = "Operator", Value = "2"});
return model;
}
and in get action of Register I have this code :
public ActionResult Create()
{
var model = RegisterViewModel.Get();
return View(model);
}
and also in razor :
<div>
#Html.LabelFor(register => register.Sex)
#Html.DropDownListFor(register => register.SelectedValue, new SelectList(Model.SelectedItemForSex, "Value", "Text"))
</div>
<div>
#Html.LabelFor(register => register.Role)
#Html.DropDownListFor(register => register.SelectedValue, new SelectList(Model.SelectedItemForRole, "Value", "Text"))
</div>
<div>
I know I have Not initialize selectedListItem for Administrator and operator , I wanna to send all of this 4 value via Get() method, How can I do this ??

Asp.net MVC3 custom validator created using dataannotation showing messages in incorrect place

I am using Asp.net MVC3, razor view engine and data annotation for model validation.
I have a form in which have to input Url details(Url and Description).Both fields are not required. But if i input one field other must be required.If i input description Url is required and is in correct format and if i enter Url then description is required.
I created a customvalidator for data annotation .It validates and output error message.
But my problem is error message generated by ValidationMessageFor is in incorrect place.
ie,if i enter description ,the required url message, is part of description.
I expect that message as part of ValidationMessageFor url field.
Can any one can help me? Thanks in advance. Folowing are the code i used
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
public sealed class IsExistAttribute : ValidationAttribute, IClientValidatable
{
private const string DefaultErrorMessage = "{0} is required.";
public string OtherProperty { get; private set; }
public IsExistAttribute (string otherProperty)
: base(DefaultErrorMessage)
{
if (string.IsNullOrEmpty(otherProperty))
{
throw new ArgumentNullException("otherProperty");
}
OtherProperty = otherProperty;
}
public override string FormatErrorMessage(string name)
{
return string.Format(ErrorMessageString, name, OtherProperty);
}
protected override ValidationResult IsValid(object value,ValidationContext validationContext)
{
if (value != null)
{
var otherProperty = validationContext.ObjectInstance.GetType()
.GetProperty(OtherProperty);
var otherPropertyValue = otherProperty
.GetValue(validationContext.ObjectInstance, null);
var strvalue=Convert.ToString(otherPropertyValue)
if (string.IsNullOrEmpty(strvalue))
{
//return new ValidationResult(FormatErrorMessage(validationContext.DisplayName));
return new ValidationResult(FormatErrorMessage(validationContext.DisplayName),new[] { OtherProperty});
}
}
return ValidationResult.Success;
}
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata,ControllerContext context)
{
var clientValidationRule = new ModelClientValidationRule()
{
ErrorMessage = FormatErrorMessage(metadata.GetDisplayName()),
ValidationType = "isexist"
};
clientValidationRule.ValidationParameters.Add("otherproperty", OtherProperty);
return new[] { clientValidationRule };
}
}
in model
[Display(Name = "Description")]
[IsExist("Url")]
public string Description { get; set; }
[Display(Name = "Url")]
[IsExist("Description")]
[RegularExpression("(http(s)?://)?([\w-]+\.)+[\w-]+(/[\w- ;,./?%&=]*)?", ErrorMessage = "Invalid Url")]
public string Url { get; set; }
and in view
<div class="editor-field">
#Html.TextBoxFor(m => m.Description )
#Html.ValidationMessageFor(m => m.Description)
</div>
<div class="editor-field">
#Html.TextBoxFor(m => m.Url)
#Html.ValidationMessageFor(m => m.Url)
</div>
unobstrusive validation logic
(function ($) {
$.validator.addMethod("isexist", function (value, element, params) {
if (!this.optional(element)) {
var otherProp = $('#' + params)
return (otherProp.val() !='' && value!='');//validation logic--edited by Rajesh
}
return true;
});
$.validator.unobtrusive.adapters.addSingleVal("isexist", "otherproperty");
} (jQuery));
You should make the validation the other way round. Change:
if (string.IsNullOrEmpty(otherPropertyValue))
{
//return new ValidationResult(FormatErrorMessage(validationContext.DisplayName));
return new ValidationResult(FormatErrorMessage(validationContext.DisplayName),new[] { OtherProperty});
}
To:
if (string.IsNullOrEmpty(Convert.ToString(value)) && !string.IsNullOrEmpty(otherPropertyValue))
{
return new ValidationResult(FormatErrorMessage(validationContext.DisplayName));
}
And remove if (value != null)
The field that will then get invalidated is the empty one, in the case the other one is filled.

To populate a dropdown in mvc3

I am new to MVC3
I am finding it difficult to create an dropdown.I have gone through all the other related questions but they all seem to be complex
I jus need to create a dropdown and insert the selected value in database
Here is what i have tried:
//Model class:
public int Id { get; set; }
public SelectList hobbiename { get; set; }
public string filelocation { get; set; }
public string hobbydetail { get; set; }
//Inside Controller
public ActionResult Create()
{
var values = new[]
{
new { Value = "1", Text = "Dancing" },
new { Value = "2", Text = "Painting" },
new { Value = "3", Text = "Singing" },
};
var model = new Hobbies
{
hobbiename = new SelectList(values, "Value", "Text")
};
return View();
}
//Inside view
<div class="editor-label">
#Html.LabelFor(model => model.hobbiename)
</div>
<div class="editor-field">
#Html.DropDownListFor( x => x.hobbiename, Model.hobbiename )
#Html.ValidationMessageFor(model => model.hobbiename)
</div>
I get an error:System.MissingMethodException: No parameterless constructor defined for this object
You are not passing any model to the view in your action. Also you should not use the same property as first and second argument of the DropDownListFor helper. The first argument that you pass as lambda expression corresponds to a scalar property on your view model that will hold the selected value and which will allow you to retrieve this value back when the form is submitted. The second argument is the collection.
So you could adapt a little bit your code:
Model:
public class Hobbies
{
[Required]
public string SelectedHobbyId { get; set; }
public IEnumerable<SelectListItem> AvailableHobbies { get; set; }
... some other properties that are irrelevant to the question
}
Controller:
public class HomeController: Controller
{
public ActionResult Create()
{
// obviously those values might come from a database or something
var values = new[]
{
new { Value = "1", Text = "Dancing" },
new { Value = "2", Text = "Painting" },
new { Value = "3", Text = "Singing" },
};
var model = new Hobbies
{
AvailableHobbies = values.Select(x => new SelectListItem
{
Value = x.Value,
Text = x.Text
});
};
return View(model);
}
[HttpPost]
public ActionResult Create(Hobbies hobbies)
{
// hobbies.SelectedHobbyId will contain the id of the element
// that was selected in the dropdown
...
}
}
View:
#model Hobbies
#using (Html.BeginForm())
{
#Html.LabelFor(x => x.SelectedHobbyId)
#Html.DropDownListFor(x => x.SelectedHobbyId, Model.AvailableHobbies)
#Html.ValidationMessageFor(x => x.SelectedHobbyId)
<button type="submit">Create</button>
}
I would create them as
Model:
public class ViewModel
{
public int Id { get; set; }
public string HobbyName { get; set; }
public IEnumerable<SelectListItem> Hobbies {get;set; }
public string FileLocation { get; set; }
public string HobbyDetail { get; set; }
}
Action
public ActionResult Create()
{
var someDbObjects= new[]
{
new { Id = "1", Text = "Dancing" },
new { Id = "2", Text = "Painting" },
new { Id = "3", Text = "Singing" },
};
var model = new ViewModel
{
Hobbies = someDbObjects.Select(k => new SelectListItem{ Text = k, Value = k.Id })
};
return View(model);
}
View
<div class="editor-label">
#Html.LabelFor(model => model.HobbyName)
</div>
<div class="editor-field">
#Html.DropDownListFor(x => x.HobbyName, Model.Hobbies )
#Html.ValidationMessageFor(model => model.HobbyName)
</div>

MVC3 dropdown list that displays mutliple properties per item

I want to have a dropdownlist in my view that displays a patient's ID, First Name, and Last Name. With the code below, it displays each patient's First Name. How can I pass all three properties into the viewbag and have them display in the dropdownlist?
Controller
public ActionResult Create()
{ViewBag.Patient_ID = new SelectList(db.Patients, "Patient_ID", "First_Name");
return View();
}
View
<div class="editor-field">
#Html.DropDownList("Patient_ID", String.Empty)
#Html.ValidationMessageFor(model => model.Patient_ID)
</div>
Thanks.
Ok, I have edited my code as follows, and I receive the error "There is no ViewData item of type 'IEnumerable' that has the key 'SelectedPatientId'."
Controller
public ActionResult Create()
{
var model = new MyViewModel();
{
var Patients = db.Patients.ToList().Select(p => new SelectListItem
{
Value = p.Patient_ID.ToString(),
Text = string.Format("{0}-{1}-{2}", p.Patient_ID, p.First_Name, p.Last_Name)
});
var Prescribers = db.Prescribers.ToList().Select(p => new SelectListItem
{
Value = p.DEA_Number.ToString(),
Text = string.Format("{0}-{1}-{2}", p.DEA_Number, p.First_Name, p.Last_Name)
});
var Drugs = db.Drugs.ToList().Select(p => new SelectListItem
{
Value = p.NDC.ToString(),
Text = string.Format("{0}-{1}-{2}", p.NDC, p.Name, p.Price)
});
};
return View(model);
}
View Model
public class MyViewModel
{
[Required]
public int? SelectedPatientId { get; set; }
public IEnumerable<SelectListItem> Patients { get; set; }
[Required]
public int? SelectedPrescriber { get; set; }
public IEnumerable<SelectListItem> Prescribers { get; set; }
[Required]
public int? SelectedDrug { get; set; }
public IEnumerable<SelectListItem> Drugs { get; set; }
}
View
#using (Html.BeginForm()) {
#Html.ValidationSummary(true)
#Html.DropDownListFor(
x => x.SelectedPatientId,
Model.Patients,
"-- Select patient ---"
)
#Html.ValidationMessageFor(x => x.SelectedPatientId)
<button type="submit">OK</button>
#Html.DropDownListFor(
x => x.SelectedPrescriber,
Model.Patients,
"-- Select prescriber ---"
)
#Html.ValidationMessageFor(x => x.SelectedPrescriber)
<button type="submit">OK</button>
}
I would recommend you not to use any ViewBag at all and define a view model:
public class MyViewModel
{
[Required]
public int? SelectedPatientId { get; set; }
public IEnumerable<SelectListItem> Patients { get; set; }
}
and then have your controller action fill and pass this view model to the view:
public ActionResult Create()
{
var model = new MyViewModel
{
Patients = db.Patients.ToList().Select(p => new SelectListItem
{
Value = p.Patient_ID.ToString(),
Text = string.Format("{0}-{1}-{2}", p.Patient_ID, p.First_Name, p.Last_Name)
});
};
return View(model);
}
and finally in your strongly typed view display the dropdown list:
#model MyViewModel
#using (Html.BeginForm())
{
#Html.DropDownListFor(
x => x.SelectedPatientId,
Model.Patients,
"-- Select patient ---"
)
#Html.ValidationMessageFor(x => x.SelectedPatientId)
<button type="submit">OK</button>
}
Easy way to accomplish that is just creating additional property on your model either by modifying model class or adding/modifying a partial class
[NotMapped]
public string DisplayFormat
{
get
{
return string.Format("{0}-{1}-{2}", Patient_ID, First_Name, Last_Name);
}
}

Resources