我有一个带有Index.cshtml Razor视图的HomeController,它使用带有验证属性的InitialChoicesViewModel。索引视图包含以下格式:
@using (Html.BeginForm("CreateCharacter", "DistributePoints", FormMethod.Get))
这是一个不同的控制器(这就是我想要的):
public class DistributePointsController : Controller
{
public ActionResult CreateCharacter(/* my form parameters */)
// ...
}
如何在表单上执行服务器端验证(例如检查ModelState.IsValid
),在错误时返回原始索引视图并使用正确的ValidationSummary
? (成功时我想返回另一个控制器的CreateCharacter视图。)
根据John H的回答,我解决了以下问题:
@using (Html.BeginForm("CreateCharacter", "Home"))
HomeController中:
[HttpPost]
// Only some of the model fields are posted, along with an additional name field.
public ActionResult CreateCharacter(InitialChoicesViewModel model, string name)
{
if (ModelState.IsValid)
{
return RedirectToAction("CreateCharacter", "DistributePoints",
new {name, model.Level, model.UseAdvancedPointSystem});
}
// Unsure how to post a collection - easier to reload from repository.
model.ListOfStuff = _repository.GetAll().ToList();
return View("Index", model);
}
我也必须在我的视图模型中添加无参数构造函数。
答案 0 :(得分:3)
[HttpPost]
public ActionResult CreateCharacter(InitialChoicesViewModel model)
{
if (ModelState.IsValid)
return RedirectToAction("SomeSuccessfulaction");
return View("~/Views/Home/Index.cshtml", model);
}
~/
表示您网站的相对根。
上面的代码符合Post-Redirect-Get模式,以防止某些类型的重复表单提交问题。它通过在表单提交成功时重定向到单独的操作,并通过返回当前视图(包含错误的ModelState
信息)来实现。
答案 1 :(得分:0)
默认情况下,ASP.NET MVC首先在\Views\[Controller_Dir]\
中进行检查,但之后,如果找不到该视图,则会检入\Views\Shared
。
如果您确实返回View("~/Views/Wherever/SomeDir/MyView.aspx")
,您可以返回任何您想要的视图。
但就你的情况而言,请尝试以下
public ActionResult CreateCharacter(SomeModel model)
{
if(!ModelState.IsValid){
return View("~/Views/Home/Index.cshtml", model )
}
return View();
}
答案 2 :(得分:0)
检查ModelState
只需在Controller中使用if语句:
if(ModelState.IsValid)
{
...
}
如果有任何错误添加,您可以向ModelState字典添加错误消息,如下所示:
ModelState.AddModelError("Somethings failed", ErrorCodeToString(e.StatusCode));
之后返回相同的视图并将其传递给您的模型
return View(model);
如果您在视图中添加“@Html.ValidationSummary()
”,它将从ModelState Dictionary中获取错误并显示它们。但如果您自己显示值,可能会使用不同的样式,您可以手动执行,看看this question
如果没有错误,您可以像这样返回您的CreateCharacter视图,只需将用户重定向到相应的操作:
return RedirectToAction("CreateCharacter","DistributePoints");