Asp MVC 5 - ModelState 无效?

Asp MVC 5 - ModelState is Invalid?

我有以下视图模型:

public class CreateCaseViewModel
{
    [Required]
    public string Subject { get; set; }

    [Required]
    [DisplayName("Post Content")]
    [UIHint("ForumEditor"), AllowHtml]
    [DataType(DataType.MultilineText)]
    public string PostContent { get; set; }

    // some other dropdown properties

}

以下控制器操作:

 [HttpPost]
 [ValidateAntiForgeryToken]
 [ValidateInput(false)]
 public ActionResult Create(CreateCaseViewModel viewModel, FormCollection collection)
 {

        // Re-populate dropdowns 
        viewModel.Categories = _unitOfWork.CategoryRepository.GetCategories();


        viewModel.Subject = collection["Subject"];
        viewModel.PostContent = collection["Description"];

        try
        {
            if (ModelState.IsValid)
            {
                // Do stuff
            }
        } 
        catch (DataException  dex  )
        {
           throw new ApplicationException("Something :", dex);
        }

        return View(viewModel);    

 }

我正在从 FormCollection 中的值手动将值分配给 PostContent,您可以从上面的代码中看到。但是我仍然不断收到 modelstate is invalid - 我返回到视图时出现验证错误“The Post Content field is required'

为什么modelstate无效?

模型在传递给您的控制器操作之前经过验证。修改模型不会改变这一点。

您需要调用 ModelState.Clear(),然后调用 Controller.TryValidateModel(model) 来重新验证模型并重置 IsValid 属性。

当您提交表单时,模型绑定器将读取发布的请求数据并将其映射到您的方法参数。之后,模型验证框架将进行验证。它不会查看您的 FormCollection 来执行此操作。因此,在您的情况下,您的模型验证失败,因为根据您的视图模型,它期望 PostContent 属性 的值并且它在那里不可用。您设置其值的操作方法代码稍后执行(此时模型验证已经发生)。

您的选择是,将输入元素名称标准化为您的视图模型 属性 名称(将 PostContent 重命名为 Description,反之亦然)

public class CreateCaseViewModel
{
    [Required]
    public string Subject { get; set; }

    [Required]
    [DisplayName("Post Content")]
    [UIHint("ForumEditor"), AllowHtml]
    [DataType(DataType.MultilineText)]
    public string Description { get; set; }    

}

现在让模型绑定器将请求主体映射到您的视图模型参数。从您的操作方法中的 FormCollection 中删除手动分配

您或许可以创建一个新的 custom model binder 来为您执行自定义映射(与您在操作方法中所做的相同)。

我会选择选项一。让默认模型绑定器处理它。