Modify the key/value pair of a ModelState MVC attribute - asp.net-mvc

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.

Related

Variable of type Long is required

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; }

Customizing model binding error messages in ASP.NET MVC 3

I'm using ASP.NET MVC 3 with Fluent Validation. I'd like all my error messages to be worded and formatted the same, whether they are validation error messages or model binding error messages.
Let's say I have the following view-model:
[Validator(typeof(PersonValidator))]
public class Person
{
[ScaffoldColumn(false)] public int Id { get; set; }
public string Name { get; set; }
public int Age { get; set; }
}
To validate this using Fluent Validation, I might use something like this:
public class EditorValidator : AbstractValidator<EditorModel>
{
public EditorValidator()
{
RuleFor(model => model.Month.Value).InclusiveBetween(0, 120)
}
}
If the user enters "abc" for Age, this causes a model binding error, not a validation error. This is because "abc" is not an int. The system never even gets to the point of asking whether "abc" is between 0 and 120, because "abc" cannot be stored in Age.
This is fine and makes sense. The problem is that the resulting error message is:
The field Age must be a number.
I'd like the message to be formatted and worded like other error message produced by Fluent Validation. In this case, I would like:
'Age' must be a number.
I realize this is only a subtle difference, but I'd like to have control of model binding error messages.
How can I customize the model binding error messages to match the error messages used by Fluent Validation?
I'm not sure if there's another way to do this, but I use Data Annotations Extensions, also available via NuGet (Install-Package DataAnnotationsExtensions.MVC3) for this exact type of thing. This package will give you an IntegerAttribute, and from there you can specify an error message like so:
[Integer(ErrorMessage = "'Age' must be a number.")]
public int Age { get; set; }
Take a look at my answer here:
How to change 'data-val-number' message validation in MVC while it is generated by #Html helper
Actually, it's a very common question that you asked, so you should've googled the stackoverflow prior to posting.

asp.net mvc 3 validation on data type

I am trying to realize valition on data type. I have used DataAnnotations, but for data type it's not showing customized message
for example when I' am trying enter string data into int typed field. How I can customize messages in this case?
If I had to guess, you sound like you want a custom message to display when validating one or more fields in your model. You can subclass the DataAnnotations.ValidationAttribute class and override the IsValid(object) method and finally setting a custom ErrorMessage value (where ErrorMessage already belongs to the ValidationAttribute class)
public class SuperDuperValidator : ValidationAttribute
{
public override bool IsValid(object value)
{
bool valid = false;
// do your validation logic here
return valid;
}
}
Finally, decorate your model property with the attribute
public class MyClass
{
[SuperDuperValidator(ErrorMessage="Something is wrong with MyInt")]
public int MyInt { get; set; }
}
If you're using out-of-the-box MVC3, this should be all you need to propertly validate a model (though your model will probably differ/have more properties, etc) So, in your [HttpPost] controller action, MVC will automagically bind MyClass and you will be able to use ModelState.IsValid to determine whether or not the posted data is, in fact, valid.
Pavel,
The DataAnnotations DataType attribute does not affect validation. It's used to decide how your input is rendered. In such a case, David's solution above works.
However, if you want to use only the built-in validation attributes, you probably need to use the Range attribute like this:
[Range(0, 10, ErrorMessage="Please enter a number between 0 and 10")]
public int MyInt { get ; set ;}
(Of course, you should really be using the ErrorMessageResourceName/Type parameters and extract out hard-coded error message strings into resx files.)
Make sure to let MVC know where to render your error message:
<%= Html.ValidationMessageFor(m => m.MyInt) %>
Or you can just use EditorForModel and it will set it up correctly.
I don't think this has been answered because I have the same issue.
If you have a Model with a property of type int and the user types in a string of "asd" then the MVC3 framework binding/validation steps in and results in your view displaying "The value 'asd' is not valid for <model property name or DisplayName here>".
To me the poster is asking can this message that the MVC3 framework is outputting be customized?
I'd like to know too. Whilst the message is not too bad if you label your field something that easily indicates an number is expected you might still want to include additional reasons so it says something like:
"The value 'asd' is not valid for <fieldname>; must be a positive whole number."
So that the user is not entering value after value and getting different error messages each time.

MVC2: Using DataAnnotations to validate DataType

I am using Entity Framework + SQL Server DB and am using partial classes with DataAnnotations to validate data. For things like Required and Range, this works fine, but I am unable to get the DataType validators to work.
Here is an example of the (custom) annotation:
[DataTypeWholeNumberAttribute(ErrorMessage = "Zip must be a whole number")]
public object Zip{ get; set; }
...and the Controller Code...
[HttpPost]
public ActionResult Edit(NamedInsuredViewModel viewModel)
{
try
{ //breakpoint here (opening squiggly bracket) shows .Zip is already null
if (ModelState.IsValid)
...save, etc...
}
}
And I know what's happening: The DataType of Zip in the database is int, so the default validation is catching that and applying the generic error message "the value [x] is not valid for [FieldName]" before my validator can get to it (to prove this, I also added the same validator to a string field, and it works just fine). What I don't know is, how can I get around that (and no, I can't change the DB to use strings for everything)?
Some suggestions have been offered in this post (http://forums.asp.net/p/1608322/4162819.aspx#4162819), but so far nothing has helped.
Thanks in advance.
PS - is there really no way to validate a primitive DataType without creating a custom Attribute?
I think the error is to pass something called "viewModel" to a Edit Action.
ViewModel is intended for pass data to a view to render it.
When you submit a form the data have to be mapped to a entity not to a viewModel.
[HttpPost]
public ActionResult Edit(YourEntity entity)
{
try
{ //breakpoint here (opening squiggly bracket) shows .Zip is already null
if (ModelState.IsValid)
...save, etc...
}
}
Apply your custom validator to the class. Then pass in your class instance as the parameter for your validator instead of as a string. Then you can perform the validation on the appropriate property regardless of type.

If I need to retrieve an object from a custom model binder should the binder interact with the service layer, the repository layer, or ...?

If I have a class similar to this:
public class Person
{
public string firstName { get; set; }
public string lastName { get; set; }
public Pet myPet { get; set; }
}
When I create a custom model binder, the Post from my form will not be sending in a Pet, it would send in data like this: firstName: "myFirstName" lastName: "myLastName" myPet: "myPetsName"
Since the Pet's name is passed in, and not the actual Pet object, the Pet object needs to be retrieved from within the model binder.
My question is, should the model binder be interacting with the Service Layer, the Repository Layer, or should it even be retrieving the Pet? The problem with the Service Layer is that I don't seem to have access to ModelState when initializing the service: ((this.ModelState) gives me an error)
_petService = new PetService(new ModelStateWrapper(this.ModelState));
If I need the model binder to create a Person object, then the Pet would need to be assigned somehow... how am I supposed to do this?
What I do is use a view/presentation model instead of binding to business objects. Remember that your users might enter invalid values, and you will need to re-display these invalid values to the user when prompting them to correct their mistakes. But your "real" business objects probably won't accept invalid values. So the view model must allow for any user input, even input the business objects won't accept.
This makes the binding easy. You don't need to hit a repository to bind, only when updating the business object with (valid) user input.

Resources