ASP.NET Core如何禁用模型验证(或者从模型状态中移除某些属性)?

ASP.NET Core如何禁用模型验证(或者从模型状态中移除某些属性)?

这是一篇4年前的文章:【经验分享】在ASP.NET Core中,如果禁用某个请求的模型验证?

事隔多年,又有网友问到这个问题。我就来重新整理一下,顺便扩展一下之前的解决办法。

=====

这是一个来自网友【David】的提问。在 AppBoxCore 项目的新增用户页面,新增一个上传按钮:

ButtonOnly="true" Required="false" ButtonIcon="ImageAdd"

OnFileSelected="@Url.Handler("filePhoto_FileSelected")"

OnFileSelectedFields="filePhoto">

后台代码:

public IActionResult OnPostFilePhoto_FileSelected(IFormFile filePhoto, IFormCollection values)

{

if (filePhoto != null)

{

string fileName = filePhoto.FileName;

// 。。。

}

return UIHelper.Result();

}

此时上传照片时,会弹出错误提示框(截图所示)。

The 用户名 field is required.The 邮箱 field is required.The 性别 field is required.The 密码 field is required.

这是因为页面模型中定义了一个绑定属性:

[CheckPower(Name = "CoreUserNew")]

public class UserNewModel : BaseAdminModel

{

[BindProperty]

public User CurrentUser { get; set; }

// ...

}

而在 POST 请求中会触发模型绑定,如果发现模型不完整就会报错。这个错误提示框是由 FineUICore 框架处理的,无需自己写代码。

现在问题就来了!

====================对于上述场景,仅仅是上传图片而无需验证 CurrentUser 模型属性,该如何处理呢?

其实也很简单,只需要在处理器中清空模型状态就可:

public IActionResult OnPostFilePhoto_FileSelected(IFormFile filePhoto, IFormCollection values)

{

ModelState.Clear();

if (filePhoto != null)

{

string fileName = filePhoto.FileName;

// 。。。

}

return UIHelper.Result();

}

Done!

====================这个问题也确实让我走了不少弯路,刚开始总想着如何禁用某些POST请求的模型验证,想着微软总能为处理器(Handler)提供一些注解(Annotation)来吧,结果查了一圈没有发现!

后来,想着换个思路:既然找不到禁用的方法,就清空模型状态,结果也是一样的。

延伸思考============================上面既然可以使用ModelState.Clear();清空所有的模型状态,那是否也可以移除模型状态中的某些属性呢?

以用户登录表单为例(用户名+密码),先看下模型定义:

namespace FineUICore.Examples.WebForms.Pages.DataModel.Models

{

public class User

{

[Required]

[Display(Name = "用户名")]

[StringLength(20)]

public string UserName { get; set; }

[Required(ErrorMessage = "用户密码不能为空!", AllowEmptyStrings = true)]

[Display(Name = "密码")]

[MaxLength(9, ErrorMessage = "密码最大为 9 个字符!")]

[MinLength(3, ErrorMessage = "密码最小为 3 个字符!")]

[DataType(DataType.Password)]

[RegularExpression("^(?:[0-9]+[a-zA-Z]|[a-zA-Z]+[0-9])[a-zA-Z0-9]*$", ErrorMessage = "密码至少包含一个字母和数字!")]

public string Password { get; set; }

}

}

页面模型中,定义一个名为 CurrentUser 的绑定属性:

[BindProperty]

public User CurrentUser { get; set; }

在页面视图中,将用户名和密码通过两个文本输入框渲染到页面中:

@* *@

注意,上述代码中我们注释掉了 CurrentUser.Password,以便在后台验证模型状态验证失败的情况。

此时提交表单,FineUICore会自动弹出模型验证失败的消息,如下图所示。

这个逻辑上是没有问题的,那个弹出框提示是FineUICore系统处理的(无需用户编码),看下事件处理函数:

public IActionResult OnPostBtnLogin_Click()

{

if (ModelState.IsValid)

{

if (CurrentUser.UserName == "admin" && CurrentUser.Password == "admin888")

{

ShowNotify("成功登录!", MessageBoxIcon.Success);

}

else

{

ShowNotify(String.Format("用户名({0})或密码({1})错误!",

CurrentUser.UserName,

CurrentUser.Password), MessageBoxIcon.Error);

}

}

return UIHelper.Result();

}

为了从模型验证状态中移除某些属性,我们可以直接这么写:

public IActionResult OnPostBtnLogin_Click()

{

ModelState.Remove("CurrentUser.Password");

if (ModelState.IsValid)

{

...

}

}

参考文章:https://stackoverflow.com/questions/16266988/exclude-fields-from-model-validation

上述文章指出,调用 ModelState.Remove() 方法虽然不够优雅,但是可以快速解决问题。更加优雅的做法是自定义一个单独的视图模型,示例代码:

public class PersonViewModel

{

[Required]

public String FirstName { get; set; }

[Required]

public String LastName { get; set; }

}

public class PersonWithEmailViewModel : PersonViewModel

{

[Required]

public String Email { get; set; }

}

相关新闻

10 大凝露推薦排行榜【2025最新】
365bet体育在线大陆

10 大凝露推薦排行榜【2025最新】

🕒 11-19 👽 9805
2015手机排行榜(15年手机排行榜)
365速发彩票app下载旧版

2015手机排行榜(15年手机排行榜)

🕒 06-27 👽 2649
说说中星九号一代机、二代机、三代机那点事儿
365速发彩票app下载旧版

说说中星九号一代机、二代机、三代机那点事儿

🕒 09-27 👽 5416
3.1.1 存储器的分类(半导体-磁芯-磁表面-光存储-ROM-RAM-永久&非永久-内存-外存-Cache)
刷(增加)网站或博客文章访问量
365bet体育在线大陆

刷(增加)网站或博客文章访问量

🕒 07-23 👽 9575
AI赋能 极致体验:荣耀Magic7系列详细测评
365bet体育在线大陆

AI赋能 极致体验:荣耀Magic7系列详细测评

🕒 10-01 👽 9087