For example, I'd like to validate a user registration form and check whether user has entered his password in "password" and "confirm password" fields, AND that those two values are the same.
Found this but is reflection really the only way?
You can try this way:
[System.ComponentModel.DataAnnotations.CustomValidation(typeof(Test), "Verify", ErrorMessage = "No match!")]
public class Test
{
[Required]
public string Password { get; set; }
[Required]
public string ConfirmPassword { get; set; }
public static ValidationResult Verify(Test t)
{
if (t.Password == t.ConfirmPassword)
return ValidationResult.Success;
else
return new ValidationResult("");
}
}
Related
WEB API --->
public async Task<IHttpActionResult> CreatePost(ChildClient c)
{
if(!ModelState.IsValid) {
throw ...
}
..
}
public class Client
{
[Required]
public bool HasBaseValue { get; set; } = true;
[Required]
public string Name { get; set; } = "stringvalue";
}
public class ChildClient : Client
{
[Required]
public bool HasFieldValue { get; set; } = true;
[Required]
public string Name1 { get; set; } = "stringvalue";
}
ModelState.Keys gives following errors: HasBaseValue,HasFieldValue if both fields are not supplied.
why it still shows in error field even though default value is set.
NOTE: default values are already populated in 'c object' when I debug and check by breakpoint.
Achieve by skipping those fields from ModelState.IsValid to validate. As those default values fields are not posted so, ModelState.IsValid considering as invalid.(because, default value populate from API but ModelState.IsValid only validate posted value).
I am trying to update user in my model object
public ActionResult AddJob(JobQueue job,HttpPostedFileBase file)
{
job.User = "itdev";
TryUpdateModel(job)
if (ModelState.IsValid)//Always returns false
{
}
}
MODEL
public class JobQueue {
[Required]
[Display(Name="JobId")]
public string JobId { get; set; }
[Required] [Display(Name = "FileName")]
public string FileName { get; set; }
[Required]
[Display(Name = "Job Run Date")]
public DateTime JobRunDate { get; set; }
[Required]
[Display(Name = "Email")]
public string Mail { get; set; }
[Required]
[Display(Name = "User")]
public string User { get; set; }
I tried using TryUpdateModel(job) and UpdateModel(job) after assigning the values.Both of these does not seem to update the model because ModelState.IsValid return false.Can someone point me in the right directions?I am using MVC3
Thanks,
Sab
I may be wrong here, but I think job.User = "itdev"; should be sufficent to update the model without using the TryUpdateModel(job) thats how we do it in our site anyway. I have never need to use any method to actually update the model itself. Just assigned values manually.
It depends on how your model is setup I guess.
You should probably post the code for your model just in case my answer isnt helpful.
I have a model class that has a couple of required fields:
public class UserMetadata
{
[Required(ErrorMessage = "Please enter a name.")]
public string Name { get; set; }
[Required(ErrorMessage = "Please enter a password.")]
public string Password { get; set; }
}
On the create view, if I don't give a name and/or password, then the validation summary errors appears. All nice and good. For the edit view, I'm only displaying the 'Name' field - I don't to show the 'Password' field.
When I save my changes on the edit page, the validation summary error appears saying that I must enter a password.
How can I control the validation of the password field, so that for the edit view, it should not bother with it? Or, am I approaching this the wrong way? I still want the 'Name' field validation to work on the edit view.
EDIT:
For my MVC project, I'm using Entity Framework. Thus, I have a 'UserMetadata' class defined so that I can attached things like '[Required]' onto certain fields on the 'User' class (which is in the EDMX file).
I should also explain that I'm using a view model eg 'UserEditViewModel' which has a property 'User' attached to it. So on my post:
[HttpPost]
public ActionResult Edit(UserEditViewModel inputViewModel)
{
if(ModelState.IsValid) { inputViewModel.User blah.... }
}
Think I rushed a bit when typing this question. Any other missing information you think is important, then please give me a shout.
Cheers.
Jas.
I ended up doing this in my action method:
ModelState.Remove("User.Password");
Now my code runs fine, only raising validation errors on the "Name" field, which is what I wanted..
ModelState.Remove("User.Password") did not work for me in MVC 3.
However, the following worked.
Option 1:
ModelState.Remove("Password")
Option 2:
ModelState.Where(m => m.Key == "Password").FirstOrDefault().Value.Errors.Clear()
Assuming you're using your UserMetadata class as a view model, you should be using a different view model per page (view).
e.g.
public class UserMetaDataCreate
{
[Required(ErrorMessage = "Please enter a name.")]
public string Name { get; set; }
[Required(ErrorMessage = "Please enter a password.")]
public string Password { get; set; }
}
and UserMetaDataEdit
public class UserMetaDataEdit
{
[Required(ErrorMessage = "Please enter a name.")]
public string Name { get; set; }
}
Basically, if the edit view doesn't need password, it shouldn't be in the model anyway.
In your controller,
public ActionResult Create()
{
return View(new UserMetaDataCreate());
}
// and subsequent post actions
[HttpPost]
public ActionResult Edit(UserMetaDataEdit vm)
{
if(ModelState.IsValid)
{
// do something
}
else
return View(vm);
}
Of course, you could go about some inheritance as your models become more complex e.g.
public class UserMetaData
{
[Required(ErrorMessage = "Please enter a name.")]
public string Name { get; set; }
}
And subclass your view models
public class UserMetaDataEdit
{
[Required(ErrorMessage = "Please enter a password.")]
public string Password { get; set; }
}
public class UserMetaDataCreate
{
}
But, I'm not sure that makes sense contextually since UserMetaData does semantically include a password.
I have a View User :
public class User {
public int id { get; set; }
public string name { get; set; }
public string email { get; set; }
}
I created a login View (strongly typed User)...
But my Login view has others attributes, like RememberMe checkbox... That attribute does not belong to User Model...
So, how is the best way to deal with that? Creating a new UserViewModel with all View attributes is an option, but I think its not the best way...
Paul
So, how is the best way to deal with that?
By using a view model:
public class LoginViewModel
{
public string Username { get; set; }
public string Password { get; set; }
public bool RememberMe { get; set; }
}
Strongly typing a login partial to a User model hardly makes sense.
For best practices I would suggest you use a ViewModel as Darin suggested. Also u can create a factory for copying ViewModel to Entity. Reflection is a bit too much here.
Here is just Darin Dimitrov example in detail.
public class User
{
public string Username { get; set; }
public string Password { get; set; }
public bool RememberMe { get; set; }
}
public class LoginViewModel
{
[Required] ... and other validation
public string Username { get; set; }
public string Password { get; set; }
public bool RememberMe { get; set; }
}
public static class UserFactory
{
public static User GetUserFromModel(LoginViewModel m, User u)
{
u.Username = m.Username;
u.Password = m.Password;
return u;
}
}
public class UserController : DefaultController
{
public ActionResult Login(LoginViewModel m)
{
if (ModelState.IsValid)
{
User u = UserFactory.GetUserFromModel(m);
....code ...
}
... code...
}
}
#Darin sorry for highjacking your example, I remember having a bit of hard time with this myself so just want to help
Could someone help me with this issue. I'm trying to figure out how to check two values on a form, one of the two items has to be filled in. How do I do a check to ensure one or both of the items have been entered?
I'm using viewmodels in ASP.NET MVC 2.
Here's a little snip of code:
The view:
Email: <%=Html.TextBoxFor(x => x.Email)%>
Telephone: <%=Html.TextBoxFor(x => x.TelephoneNumber)%>
The viewmodel:
[Email(ErrorMessage = "Please Enter a Valid Email Address")]
public string Email { get; set; }
[DisplayName("Telephone Number")]
public string TelephoneNumber { get; set; }
I want either of these details to be provided.
Thanks for any pointers.
You can probably do this in much the same way as the PropertiesMustMatch attribute that comes as part of the File->New->ASP.NET MVC 2 Web Application.
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)]
public sealed class EitherOrAttribute : ValidationAttribute
{
private const string _defaultErrorMessage = "Either '{0}' or '{1}' must have a value.";
private readonly object _typeId = new object();
public EitherOrAttribute(string primaryProperty, string secondaryProperty)
: base(_defaultErrorMessage)
{
PrimaryProperty = primaryProperty;
SecondaryProperty = secondaryProperty;
}
public string PrimaryProperty { get; private set; }
public string SecondaryProperty { get; private set; }
public override object TypeId
{
get
{
return _typeId;
}
}
public override string FormatErrorMessage(string name)
{
return String.Format(CultureInfo.CurrentUICulture, ErrorMessageString,
PrimaryProperty, SecondaryProperty);
}
public override bool IsValid(object value)
{
PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(value);
object primaryValue = properties.Find(PrimaryProperty, true /* ignoreCase */).GetValue(value);
object secondaryValue = properties.Find(SecondaryProperty, true /* ignoreCase */).GetValue(value);
return primaryValue != null || secondaryValue != null;
}
}
The key part of this function is the IsValid function that determines if one of the two parameters has a value.
Unlike normal Property-based attributes, this is applied to the class level and can be used like so:
[EitherOr("Email", "TelephoneNumber")]
public class ExampleViewModel
{
[Email(ErrorMessage = "Please Enter a Valid Email Address")]
public string Email { get; set; }
[DisplayName("Telephone Number")]
public string TelephoneNumber { get; set; }
}
You should be able to add as many as these as you need per form, but if you want to force them to enter a value into one of more than two boxes (Email, Telephone or Fax for example), then you would probably be best changing the input to be more an array of values and parse it that way.