I have one ViewModel that has property Id of type long without attribute [required]. This model I use for search.
Problem : Why always when i try to make search request and input for property Id leave empty i get validation error as Id field is required ?
Make your model property nullable.
public long? myprop { get; set; }
Related
Is there any way to modify the key of an ModelState attribute? I receive the following JSON response:
{"Message":"The request is invalid.",
"ModelState":
{
"supplier.SupplierWarehouses[2].Location":["Location name is too long, maximum 50 characters"]
}
}
I want to modify the supplier.SupplierWarehouses[2].Location to something more simple like SupplierLocation.
Is there any way to do this directly in the Model? My current Model is:
public class SupplierWarehouseMetadata
{
[StringLength(50,ErrorMessage="Location name is too long, maximum 50 characters")]
public string Location { get; set; }
}
No, because this isn't just about ModelState. The post value has that name because that's what the modelbinder needs in order to bind it correctly to the appropriate property on your model on post. If you modify the name, then the value will no longer bind.
That said, what is the goal here anyways? If you're concerned about what's coming back in the JSON, just return something custom instead of dumping ModelState.
Following is one of the property in my MVC model.
[Display(Name = "Event ID")]
[MaxLength(8, ErrorMessage = "Event ID can be of maximum 8 characters long")]
[Required(ErrorMessage="Event ID must be entered")]
public Nullable<int> ID_EVENTO { get; set; }
I have bound the model with a View, and when I try to click "Submit" button, it gives following runtime error -
Unable to cast object of type 'System.Int32' to type 'System.Array'
While, if I remove the "MaxLength" attribute, it starts working.
What could be the issue here?
MaxLength is used to specify the maximum length of array or string data allowed in a property.
Your ID_EVENTO is a nullable int (rather than array or string), that's why the attribute doesn't work. Sounds like you either want to remove the attribute or use a different one - Range or something?
I have an EF entity Respondent that is automatically generated by EF from the database).
I had to expand this entity to add some validation rules and attributes to use within my View:
[MetadataType(typeof(RespondentMetadata))]
public partial class Respondent { }
public class RespondentMetadata
{
[Required]
[Display(Name = "First Name")]
public string FirstName { get; set; }
}
Now, in my controller, I need to check if this Respondent object has indeed value in FirstName (without checking the value explicitly, because I may have large number of such properties with various validation rules).
This check can be anywhere not necessary in [HttpPost] action (so, ModelState.IsValid N/A here).
How can I validate the entire entity anywhere in code?
Thanks.
The 'Text-Book-Way' is to add validation to your Model.
then you can make a check like
if (Respondent.IsValid())
{
}
You could use the Validator.ValidateObject method in order to perform validation anywhere in the code, but for that you need to stop using the MetadataTypeAttribute and explicitly associate the metadata class using the TypeDescriptor.AddProviderTransparent method.
Sample:
var respondent = new Respondent();
var provider = new AssociatedMetadataTypeTypeDescriptionProvider(
typeof (Respondent),
typeof (RespondentMetadata));
TypeDescriptor.AddProviderTransparent(provider, typeof (Respondent));
Validator.ValidateObject(
respondent,
new ValidationContext(respondent, null, null));
The Validator class does not seem to honor the attribute so this is the only workaround that I'm aware.
In our ASP.NET MVC 4 application, one of the models has a field of the DateTime type. When editing such model objects via a form, the value for the DateTime field has to be non-empty and on the format yyyy-MM-dd H:mm:ss (e.g., 2012-10-17 10:49:00). How do I ensure this field is correctly validated in the application? I've tried the following annotations:
[System.ComponentModel.DataAnnotations.Required]
[System.ComponentModel.DataAnnotations.DisplayFormat(DataFormatString="yyyy-MM-dd H:mm:ss",
ApplyFormatInEditMode=true)]
However, validation of form data doesn't require all components of the format to be present. For instance, the value '2012-10-17' is accepted (leaving out the 'H:mm:ss' part). It's just verified that the field contains a valid DateTime string.
How should I ensure that this DateTime field is indeed on my specified format (yyyy-MM-dd H:mm:ss)?
Alternative solution - view-only model class
Darin's solution is of course valid, but it's not the only one you can use. And it would require you to write more complex code than with this solution that I'm going to show you here.
So this is an alternative. I'd suggest that instead of creating a custom model binder you rather create a separate view model class that instead of taking DateTime takes a string where you can set as complex validation regular expression as you like. And then have a method on it that would translate it to your application/domain model class instance (and back).
// suppose this app model
public class User
{
[Required]
public string Name { get; set; }
[Required]
public DateTime DateOfBirth { get; set; }
}
public class ViewUser
{
[Required]
public string Name { get; set; }
[Required]
[RegularExpression("\d{4}-\d{2}-\d{2}(?:\s\d{1,2}:\d{2}:\d{2})?")]
public string DateOfBirth { get; set; }
public ViewUser(User user)
{
this.Name = user.Name;
this.DateOfBirth = user.DateOfBirth.ToString("yyyy-MM-dd H:mm:ss");
}
public User ToPoco()
{
return new User {
Name = this.Name,
DateOfBirth = DateTime.Parse(this.DateOfBirth, "yyyy-MM-dd H:mm:ss")
};
}
}
With a bit of tweaking you could inherit ViewUser from User class and use new keyword on DateOfBirth and use base property to store correct typed value. In that case you wouldn't need the ToPoco method.
Note: you will have to use DateTime.TryParseExact method to parse your dates because they may include time or they may not. I didn't include that in my code because it depends on the exact requirements of your date input.
You could write a custom model binder which will use the exact format you have specified in the DisplayFormat attribute. I have shown an example of how this could be achieved in this post.
Also don't be confused into thinking that the DisplayFormat attribute overrides the Required attribute. The DisplayFormat is only used for displaying the field in the input field. It is not a validation attribute. It has strictly nothing to do with validation and when the form is POSTed to the server it is never used.
I am working with a ASP.NET MVC4 application. I have created a view model which contains menu items and I can switch languages in page by Resources file.
#region Properties
[Display(Name = "MenuText", ResourceType = typeof(App.App_Resources.Menu))]
public string menuText { get; set; }
public List<MenuItem> menuItems { get; set; }
#endregion
However, I want to get this resource string in my .cshtml file, then I try as following
#model App.Models.MenuViewModel
#Html.LabelFor(model => model.menuText) <- Success
#Html.DisplayForModel("menuText") <- Success
#Model.menuText <- Fail
I inserted a break point and found out that Model contains a property which name is menuText but value is null. And I checked that Html also contains a property Model and its menuText also is null.
However, menuItems has items since I assign objects in constructor.
Why the menuText cannot be initialized and assigned value to it?
Why I can succeed to show the resource string with first two but Model.menuText is null and fail to show anything? What is different between the models in #Html.XXX and #Model?
#Model.menuText retrieves the raw string value stored within the menuText property. Attributes are ignored.
Using LabelFor causes the Display attribute of the property to be examined. The localised string is stored in the attribute, not the property.
Note that I think the Model object/class should not be used to store information for display (that's what ViewData is for), but rather only for round-trip data that is sent from the client to the server.