c# web api 请求验证过滤器,上下文值为空 - 参数列表不是

标签 c# asp.net-mvc validation asp.net-web-api

我正在使用 C# Web api,想要为所有请求创建一个过滤器。

我对每个请求都有一个指定的类,所以我只想添加一些数据注释并完成验证。

问题是我每次在 actionContext.ModelState.IsValid

上都会得到 true

我已在配置中添加了过滤器:

config.Filters.Add(new RequestValidationFilter());

验证方法与网络中的其他方法类似

public class RequestValidationFilter : ActionFilterAttribute
{
    public override void OnActionExecuting(HttpActionContext actionContext)
    {
        if (actionContext.ModelState.IsValid == false)
        {
            var errors = actionContext.ModelState
                                      .Values
                                      .SelectMany(m => m.Errors
                                                        .Select(e => e.ErrorMessage));

            actionContext.Response = actionContext.Request.CreateErrorResponse(
                HttpStatusCode.BadRequest, actionContext.ModelState);

            actionContext.Response.ReasonPhrase = string.Join("\n", errors);
        }
    }
}

我有以下方法:

[HttpPost, Route("User/Login")]
public async Task<Responses.Login> Login(Requests.Login request)
{
      ...//some login logic
}

而且,我的模型是:

public class Requests
{
    public class Login
    {
        [Required(AllowEmptyStrings = false, ErrorMessage = "Email address  cannot be empty!")]
[MinLength(5)]
            public string Email;
        [Required]
        public string Password;
    }
}

我正在发送一个空请求或电子邮件密码为空的请求,但actionContext.ModelState.IsValid仍对其进行评估作为true

附件是发送电子邮件但未发送密码时的图像。

enter image description here

在评论之后,这是我通过 Advanced Rest Client chrome 插件提出的请求

enter image description here 注意

图像实际上显示键和值是空的,而实际上它们已被提供..

编辑

我也尝试过的事情数量:

  1. 删除所有其他过滤器,为什么?也许上下文被另一次阅读弄乱了。
  2. 正在发送字段方面的有效请求,但电子邮件长度为 1 个字符。为什么?也许 Required 的工作方式与其他方式不同,但仍然没有关于最小长度问题。
  3. 我没有为 Login 对象创建一个单独的独立类,而不是嵌套对象。为什么?我认为它的嵌套验证可能不是递归的。
  4. 逐一循环Arguments列表并验证为对象,答案始终为真。永远不会失败,为什么?因为我几乎要认输了。
  5. 没有像我在问题中描述的那样将过滤器添加到配置中,而是尝试了 GlobalConfiguration.Configuration.Filters.Add(new RequestValidationFilter());

最佳答案

您需要添加 { get;放; } 在模型属性之后:

public class Login
{
    [Required(AllowEmptyStrings = false, ErrorMessage = "Email address cannot be empty!")]
    [MinLength(5)]
    public string Email { get; set; }

    [Required]
    public string Password { get; set; }
}

这是必要的,因为 ASP.NET 的默认模型验证仅包含具有公共(public) get 方法的属性。来自 PropertyHelper.cs ,以下是一些确定模型上的属性是否包含在验证中的代码:

// Indexed properties are not useful (or valid) for grabbing properties off an object.
private static bool IsInterestingProperty(PropertyInfo property)
{
    return property.GetIndexParameters().Length == 0 &&
        property.GetMethod != null &&
        property.GetMethod.IsPublic &&
        !property.GetMethod.IsStatic;
}

此方法用于过滤 MVC/Web API 中默认模型绑定(bind)中使用的属性。请注意,它正在检查属性上是否存在 GetMethod 并且它是公共(public)的。由于您的类在其属性上没有 get 方法,因此它们被忽略。

如果你想了解更多,你可以花很多时间浏览ASP.NET MVC source 。我认为 github 上的代码适用于较新版本的 ASP.NET,但似乎很多相同的逻辑适用于您正在使用的版本。

关于c# web api 请求验证过滤器,上下文值为空 - 参数列表不是,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35752597/

相关文章:

c# - Server.MapPath 不返回映射到 Web-App 子文件夹中的虚拟目录的正确物理路径

javascript - 非数字正则表达式 + 仅允许单个 "."用于输入验证

c# - Break inside switch 无法终止 FOR 循环

c# - 在单声道下运行支持 SSL 的 TCP 服务器的问题

c# - 在 asp.net MVC C# 中单击“提交”时消失控件 HTML

javascript - 在插入 mysql 之前如何验证字符串?

ruby - 导轨 4 : Validating associated ActiveRecord models when using a Form Object

c# - 区分整数的位

c# - 使用OLEDB从Stream读取AccessFile到DataSet

asp.net-mvc - ASP.NET MVC中的单线程单元COM组件