C# ModelState.IsValid=true是否保证传递的模型参数不为null?

C# ModelState.IsValid=true是否保证传递的模型参数不为null?,c#,asp.net-mvc,asp.net-core-mvc,C#,Asp.net Mvc,Asp.net Core Mvc,假设我们有Create和Edit操作方法,它们由HttpPost属性化,并且它们有一个model类型的参数,例如BlogViewModel,如下所示 [HttpPost] public IActionResult Create(..., BlogViewModel model) { .... } [HttpPost] public IActionResult Edit(..., BlogViewModel model) { .... } if(ModelState.IsValid) { //

假设我们有
Create
Edit
操作方法,它们由
HttpPost
属性化,并且它们有一个
model
类型的参数,例如
BlogViewModel
,如下所示

[HttpPost]
public IActionResult Create(..., BlogViewModel model)
{
....
}

[HttpPost]
public IActionResult Edit(..., BlogViewModel model)
{
....
}
if(ModelState.IsValid)
{
// do something 
}
在他们的身体里,我们通常做如下验证

[HttpPost]
public IActionResult Create(..., BlogViewModel model)
{
....
}

[HttpPost]
public IActionResult Edit(..., BlogViewModel model)
{
....
}
if(ModelState.IsValid)
{
// do something 
}
在这里,
do something
可以是访问
模型的属性的操作

问题: 我不确定是否存在
model
变为
null
的可能性。如果
model
null
,则
执行某些操作(例如访问
model
的属性)将引发异常

我读了很多例子(来自互联网和教科书),我还没有看到有人在做下面的双重检查

if(model!=null)
{
    if(ModelState.IsValid)
    {
    // do something
    }
}

很可能,条件
ModelState.IsValid
true
保证
model
不是
null


我在这里的假设正确吗?恐怕我在做一个定时炸弹的假设

要回答您的问题,否,ModelState.IsValid不会检查您的模型是否为null,如果出现这种情况,将抛出错误

在API中,如果在构建请求模型时出错,并且与端点期望的不匹配,则很容易出现空模型

或者其他人可以查看您的网站,查看API调用并决定玩得开心,然后用没有有效模型的请求淹没您的API

有很多方法可以在一个地方检查空模型,比如这里:

什么是模型状态? ModelState表示在POST期间提交给服务器的名称和值对的集合

模型状态下是什么? 以下是来自同一调试器会话的这些值的外观: 每个属性都有一个ValueProviderResult实例,其中包含提交给服务器的实际值

模型状态中的验证错误。。。 例如:-

在本例中,如果您的姓氏包含超过50个字符,则ModelState为false,因为vaueProvidedResult有异常

希望你对ModelState有所了解

您的问题的答案是您可以从modelState处理模型


如果model null automatically modelState无效

,答案就是否定的

表示将已发布表单(标记为
BeginForm
)绑定到操作方法的尝试,该操作方法还包括验证信息。它带有默认的模型活页夹设置,指定哪些验证设置应包括在viewmodel中,例如,
RequiredAttribute
,因此必填字段的空值检查取决于存在哪些验证设置,而不是
ModelStateDictionary
本身

提交表单时,
DefaultModelBinder
设置viewmodel绑定,并检查绑定的viewmodel类中的每个属性是否存在验证设置(即属性)。如果提交的值与设置的条件不匹配(例如,标记为
RequiredAttribute
的属性中的
null
/空值),它将向属性添加验证错误,并随后返回false,因为它取决于
错误
属性计数。以下是
IsValid
检查机制取自:

公共类ModelStateDictionary:IDictionary { 专用只读词典; 公共ICollection值 { 获取{return\u innerDictionary.Values;} } 公共布尔是有效的 { 获取{返回值.All(modelState=>modelState.Errors.Count==0); } }
因此,如果所有模型属性在未指定
RequiredAttribute
的情况下设置为null/empty,则由于不存在验证属性,
ModelStateDictionary.IsValid
值仍为
true
,模型绑定可以工作

类似问题:


只有当您有其他错误时,模型才会为
null
code@StephenMuecke:那么是否有必要始终按照上面代码中所示进行双重检查?或者
ModelState.IsValid=true
不保证
model!=null
?实际上,ModelState.IsValid会检查ModelState是否添加了任何错误,因此在在模型可为null的情况下,即使模型为null,ModelState也有效。但是,在您的情况下,post请求中需要BlogViewModel,因此具有null模型的请求将引发异常。因此,在这种情况下,您不需要检查模型是否为null。
ModelState
有效。模型为
null
(只有当
ModelBinder
试图设置无效的属性值时,该属性才无效)。如果请求中没有传递与模型属性名称匹配的值,或者如果您将参数命名为与模型中的一个属性相同,则模型将为
null
。我个人认为没有必要这样做(而且从未见过这样的例子)。在上面的第二种情况下,您将在发布之前更正此问题,如果在请求中未发送与您的模型属性匹配的值,您可以假定其为恶意用户,因此如果他们看到异常将导致的错误页面,该怎么办。OP未询问
ModelState
是什么!@StephenMuecke yes回答整个问题他需要了解您可以从modelState处理模型,如果模型为null,则modelState自动无效wrong@StephenMuecke理论上可能吗?我从未遇到过这种情况。如果请求中没有发送与模型属性匹配的内容,那么模型将不会由
DefaultModelBinder
初始化,因此未向
ModelState
添加任何内容,并且该文件将有效。
public class ModelStateDictionary : IDictionary<string, ModelState>
{
    private readonly IDictionary<string, ModelState> _innerDictionary;

    public ICollection<ModelState> Values
    {
        get { return _innerDictionary.Values; }
    }

    public bool IsValid
    {
        get { return Values.All(modelState => modelState.Errors.Count == 0); 
    }
}