Using [JsonProperty ("name")] in ModelState.Errors

We have a couple of models that override the name through JsonProperty, but this causes a problem when we get validation errors through ModelState. For instance:

class MyModel
{
    [JsonProperty("id")]
    [Required]
    public string MyModelId {get;set;}
}

class MyModelController
{
    public IHttpActionResult Post([FromBody] MyModel model)
    {
        if (!ModelState.IsValid)
        {
            return HttpBadRequest(ModelState);
        }

        /* etc... */
    }
}

The above Mail will return an error The MyModelId field is required.that is inaccurate. We would like to say that The id field is required.. We tried to use [DataMember(Name="id")], but we get the same result.

Question 1: Is it possible to get ModelState errors to show the name of the JSON property, and not the name of the C # property, other than providing our own error messages for each attribute [Required]?

- Update -

" " . , , , , ...

https://gist.github.com/Blackbaud-JasonTremper/b64dc6ddb460afa1698daa6d075857e4

2. , ModelState.Key <parameterName>.<reflectedProperty> , ?

3: , JSON, [DataMember] [JsonProperty]?

+4
2

DisplayName?

displayname

, [Required].

[Required(ErrorMessage = "Name is required")]

+2

, , WebAPI. modelState , , Json Property.

  • ValidateModelStateFilter
  • [ValidateModelStateFilter]

:

public class ValidateModelStateFilter : ActionFilterAttribute
{
    public override void OnActionExecuting(HttpActionContext actionContext)
    {
        var descriptor = actionContext.ActionDescriptor;
        var modelState = actionContext.ModelState;

        if (descriptor != null)
        {
            var parameters = descriptor.GetParameters();

            var subParameterIssues = modelState.Keys
                                               .Where(s => s.Contains("."))
                                               .Where(s => modelState[s].Errors.Any())
                                               .GroupBy(s => s.Substring(0, s.IndexOf('.')))
                                               .ToDictionary(g => g.Key, g => g.ToArray());

            foreach (var parameter in parameters)
            {
                var argument = actionContext.ActionArguments[parameter.ParameterName];

                if (subParameterIssues.ContainsKey(parameter.ParameterName))
                {
                    var subProperties = subParameterIssues[parameter.ParameterName];
                    foreach (var subProperty in subProperties)
                    {
                        var propName = subProperty.Substring(subProperty.IndexOf('.') + 1);
                        var property = parameter.ParameterType.GetProperty(propName);
                        var validationAttributes = property.GetCustomAttributes(typeof(ValidationAttribute), true);

                        var value = property.GetValue(argument);

                        modelState[subProperty].Errors.Clear();
                        foreach (var validationAttribute in validationAttributes)
                        {
                            var attr = (ValidationAttribute)validationAttribute;
                            if (!attr.IsValid(value))
                            {
                                var parameterName = GetParameterName(property);
                                // modelState.AddModelError(subProperty, attr.FormatErrorMessage(parameterName));
                                modelState.AddModelError(parameterName, attr.FormatErrorMessage(parameterName));
                            }
                        }
                    }
                }


            }
        }

    }

    private string GetParameterName(PropertyInfo property)
    {
        var dataMemberAttribute = property.GetCustomAttributes<DataMemberAttribute>().FirstOrDefault();
        if (dataMemberAttribute?.Name != null)
        {
            return dataMemberAttribute.Name;
        }

        var jsonProperty = property.GetCustomAttributes<JsonPropertyAttribute>().FirstOrDefault();
        if (jsonProperty?.PropertyName != null)
        {
            return jsonProperty.PropertyName;
        }

        return property.Name;
    }
}
0

Source: https://habr.com/ru/post/1660985/


All Articles