首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在ModelState.Errors中使用[ModelState.Errors(“name”)]

在ModelState.Errors中使用[ModelState.Errors(“name”)]
EN

Stack Overflow用户
提问于 2016-11-16 19:11:06
回答 3查看 4.1K关注 0票数 12

我们有几个通过JsonProperty覆盖名称的模型,但是当我们通过ModelState获得验证错误时,这会引起问题。例如:

代码语言:javascript
复制
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 MyModelId field is required.,这是不准确的。我们希望这个词是The id field is required.。我们尝试使用[DataMember(Name="id")],但得到了相同的结果。

问题1:除了在每个必需属性上提供我们自己的错误消息之外,是否有一种方法可以让ModelState错误显示JSON属性名称而不是C#属性名称?

-更新

我一直在玩这个,并找到了一个“自己动手”的方法,用于使用自定义属性名称重新创建错误消息。我真的希望有一个内置的方法来做这件事,但这似乎是工作.

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

问题2:是否可以假定ModelState.Key与<parameterName>.<reflectedProperty>语法匹配,或者在某些情况下可能不符合?

问题3:是否有一种更简单的方法来确定JSON的参数名称,而不是通过对[DataMember][JsonProperty]属性的反射进行搜索?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-11-16 21:06:04

你试过使用DisplayName属性吗?

displayname attribute vs display attribute

此外,还可以将错误消息分配给[Required]属性。

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

票数 3
EN

Stack Overflow用户

发布于 2017-04-07 07:18:11

我也面临这个问题,我修改了一些代码从您的链接,以适应我的WebAPI。modelState还将存储旧键,它是模型的变量名,加上Json属性名。

  1. 首先,创建过滤器ValidateModelStateFilter
  2. 添加以上控制器方法的[ValidateModelStateFilter]

过滤器源代码:

代码语言:javascript
复制
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;
    }
}
票数 3
EN

Stack Overflow用户

发布于 2019-11-11 12:49:44

您可以访问参数类型,获取json名称,然后用json名称替换属性名。就像这样:

代码语言:javascript
复制
var invalidParameters = (from m in actionContext.ModelState
                         where m.Value.Errors.Count > 0
                         select new InvalidParameter
                         {
                              ParameterName = m.Key,
                              ConstraintViolations = (from msg in m.Value.Errors select msg.ErrorMessage).ToArray()
                         }).AsEnumerable().ToArray();

if (actionContext.ActionDescriptor.Parameters.Count == 1)
{
    var nameMapper = new Dictionary<string, string>();

    foreach (var property in actionContext.ActionDescriptor.Parameters[0].ParameterType.GetProperties())
    {
        object[] attributes = property.GetCustomAttributes(typeof(JsonPropertyNameAttribute), false);

        if (attributes.Length != 1) continue;

        nameMapper.Add(property.Name, ((JsonPropertyNameAttribute) attributes[0]).Name);
    }

    var modifiedInvalidParameters = new List<InvalidParameter>();


    foreach (var invalidParameter in invalidParameters)
    {
        if(invalidParameter.ParameterName != null && nameMapper.TryGetValue(invalidParameter.ParameterName, out var mappedName))
        {
            var modifiedConstraintViolations = new List<string>();

            foreach (var constraintViolation in invalidParameter.ConstraintViolations ?? Enumerable.Empty<string>())
            {
                modifiedConstraintViolations.Add(constraintViolation.Replace(invalidParameter.ParameterName, mappedName));
            }

            modifiedInvalidParameters.Add(new InvalidParameter
            {
                ParameterName = mappedName,
                ConstraintViolations = modifiedConstraintViolations.ToArray()
            });
        }
        else
        {
            modifiedInvalidParameters.Add(invalidParameter);
        }
    }

    invalidParameters = modifiedInvalidParameters.ToArray();
}
代码语言:javascript
复制
public struct InvalidParameter
{
    [JsonPropertyName("parameter_name")]
    public string? ParameterName { get; set; }

    [JsonPropertyName("constraint_violations")]
    public string[]? ConstraintViolations { get; set; }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40640386

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档