我正在使用 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
附件是发送电子邮件但未发送密码时的图像。
在评论之后,这是我通过 Advanced Rest Client chrome 插件提出的请求
图像实际上显示键和值是空的,而实际上它们已被提供..
编辑
我也尝试过的事情数量:
- 删除所有其他过滤器,为什么?也许上下文被另一次阅读弄乱了。
- 正在发送字段方面的有效请求,但电子邮件长度为 1 个字符。为什么?也许
Required
的工作方式与其他方式不同,但仍然没有关于最小长度问题。 - 我没有为
Login
对象创建一个单独的独立类,而不是嵌套对象。为什么?我认为它的嵌套验证可能不是递归的。 - 逐一循环
Arguments
列表并验证为对象,答案始终为真。永远不会失败,为什么?因为我几乎要认输了。 - 没有像我在问题中描述的那样将过滤器添加到配置中,而是尝试了
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/