ModelState.IsValid = False

时间:2021-05-12 13:00:38

标签: c# asp.net-mvc asp.net-core

ModelState 抛出一个错误,参数 [UserId] 之一是 null。我的表单上没有设置该字段。它正在控制器中设置。

如何将其从 ModelState.IsValid 测试中删除?

    [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> Create([Bind("Id,UserId,Created,TimeStamp,Name,Role,Description,Partner,PartnerAmount,Competitor,IsDeleted")] Relationship relationship)
    {
        relationship.UserId = User.Identity.Name.Replace(@"XXXXX\","");
        relationship.Created = DateTime.Now;
        relationship.TimeStamp = DateTime.Now;
        relationship.IsDeleted = false;
        if (ModelState.IsValid)
        {
            _context.Add(relationship);
            await _context.SaveChangesAsync();
            return RedirectToAction(nameof(Index));
        }
        return View(relationship);
    }

它不会通过 UserId 的 ModelState.IsValid b/c。但是,它不会检查 Created、Timestamp 或 IsDeleted。为什么它不检查那些,但它会检查 UserId?我的模型中所有这些字段都是必需的。

3 个答案:

答案 0 :(得分:0)

从视图模型中删除该字段。如果您没有,请继续创建。在您的视图中使用实体会产生安全漏洞,因为攻击者可以设置您一旦发布就无法更改的字段。

使用视图模型可确保只有允许更改的字段在浏览器中可用。

如果您仍想使用您的实体,请将 UserId 更改为 int?,这会告诉模型验证器不必设置它。

您还可以删除验证 ModelState["UserId"].Errors.Clear();但我强烈反对这样做。使用特定的视图模型。

答案 1 :(得分:0)

您不能通过更改控制器内部的任何属性来更改 ModelState.IsValid。 IsValid 仍将是相同的,因为错误列表将是相同的。应该在模型到达控制器之前分配 UserId。

因此,如果 UserId=0 可以为空,并在视图表单内的某处添加这一行,

<input type="hidden" asp-for="@Model.UserId" value="@Model.UserId"/>

答案 2 :(得分:0)

在控制器动作方法中,尝试使用Rerun validation,调用TryValidateModel方法,如下所示:

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("Id,UserId,Created,TimeStamp,Name,Role,Description,Partner,PartnerAmount,Competitor,IsDeleted")] Relationship relationship)
{
    relationship.UserId = User.Identity.Name.Replace(@"XXXXX\","");
    relationship.Created = DateTime.Now;
    relationship.TimeStamp = DateTime.Now;
    relationship.IsDeleted = false;

    if (!TryValidateModel(relationship, nameof(relationship)))
    { 
        return View(relationship);
    }
    _context.Add(relationship);
    await _context.SaveChangesAsync();
    return RedirectToAction(nameof(Index));
}