I have this asp.net core model:

public class MyModel
{
    [ModelBinder(Name = "id")]
    [StringLength(36, MinimumLength = 3)]
    public string ObjectId { get; set; }
}

I added the ModelBinder attribute in order to rename the "ObjectId" field to "id".

When I trying to submit the model with bad values. For example:

{
    "id": "1111111111111111111111111111111111111111111111111111111111111111111111111111"
}

I'm getting back this response from the server:

{
     "id":["The field ObjectId must be a string with a minimum length of 3 and a maximum length of 36."]
}

Expected output:

{
     "id":["The field id must be a string with a minimum length of 3 and a maximum length of 36."]
}

That's strange because the key ("id") was written in the right case. But in the value ("ObjectId") it was written in wrong.

My client shouldn't be aware of ObjectId. He just know id. How to fix messages like these?

Thanks.

3 Answers

1
user2491278 On Best Solutions

The solution is to use DisplayName attribute:

public class MyModel
{
  [ModelBinder(Name = "id")]
  [StringLength(36, MinimumLength = 3)]
  [DisplayName("id")]
  public string Id {get; set;}
}
0
Black Frog On

You can set a custom error message on StringLengthAttribute Class.

public class MyModel
{
    [ModelBinder(Name = "id")]
    [StringLength(36, MinimumLength = 3, ErrorMessage="The field id must be a string with a minimum length of {1} and a maximum length of {2}.")]
    public string ObjectId { get; set; }
}

Excerpt from documentation page:

You can use composite formatting placeholders in the error message: {0} is the name of the property; {1} is the maximum length; and {2} is the minimum length. The placeholders correspond to arguments that are passed to the String.Format method at runtime.

0
Tao Zhou On

For StringLength, it uses the default property name for constructing the error message which is expected.

If you prefer using the Name arugment from ModelBinder, you could implement your own StringLength arribute like

public class CustomStringLength : StringLengthAttribute
{
    public CustomStringLength(int maximumLength) 
        : base(maximumLength)
    {
    }
    public override string FormatErrorMessage(string name)
    {

        return base.FormatErrorMessage(name);
    }
    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        var propertyName = validationContext.DisplayName;
        var propertyAttribute = validationContext.ObjectType
                                    .GetProperty(propertyName)
                                    .GetCustomAttribute(typeof(ModelBinderAttribute));
        if (propertyAttribute is ModelBinderAttribute modelBinderAttribute)
        {
            validationContext.DisplayName = modelBinderAttribute.Name;
        }
        //validationContext.DisplayName = "Id";
        return base.IsValid(value, validationContext);
    }
}

Then use it like

public class MyModel
{
    [ModelBinder(Name = "id")]
    [CustomStringLength(36, MinimumLength = 3)]
    public string ObjectId { get; set; }
}