Asp MVC 5 - ModelState无效?

时间:2017-10-28 14:51:02

标签: asp.net-mvc validation viewmodel modelstate

我有以下视图模型:

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无效?

2 个答案:

答案 0 :(得分:1)

模型在传递给控制器​​操作之前已经过验证。修改模型不会改变它。

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

答案 1 :(得分:1)

当您提交表单时,模型绑定器将读取已发布的请求数据并将其映射到您的方法参数。之后,模型验证框架将进行验证。它不会看你的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,为您执行自定义映射(与您在操作方法中执行的操作相同)。

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

相关问题