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 来为您执行自定义映射(与您在操作方法中所做的相同)。
我会选择选项一。让默认模型绑定器处理它。
我有以下视图模型:
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 来为您执行自定义映射(与您在操作方法中所做的相同)。
我会选择选项一。让默认模型绑定器处理它。