我有一个模型BlogPostViewModel
的视图:
public class BlogPostViewModel
{
public BlogPost BlogPost { get; set; }
public PostComment NewComment { get; set; }
}
当操作方法BlogPost
被命中时,将呈现此视图。该视图通过迭代Model.BlogPost.PostComments
显示有关博客帖子的信息以及博客帖子上的评论列表。下面我有一个允许用户发布新评论的表单。此表单会发布到其他操作AddComment
。
[HttpPost]
public ActionResult AddComment([Bind(Prefix = "NewComment")] PostComment postComment)
{
postComment.Body = Server.HtmlEncode(postComment.Body);
postComment.PostedDate = DateTime.Now;
postCommentRepo.AddPostComment(postComment);
postCommentRepo.SaveChanges();
return RedirectToAction("BlogPost", new { Id = postComment.PostID });
}
我的问题在于验证。我如何验证此表单?视图的模型实际上是BlogPostViewModel
。我是验证的新手,很困惑。表单使用强类型帮助器绑定到NewComment
的{{1}}属性,并且我也包含了验证助手。
BlogPostViewModel
如何在@using (Html.BeginForm("AddComment", "Blog")
{
<div class="formTitle">Add Comment</div>
<div>
@Html.HiddenFor(x => x.NewComment.PostID) @* This property is populated in the action method for the page. *@
<table>
<tr>
<td>
Name:
</td>
<td>
@Html.TextBoxFor(x => x.NewComment.Author)
</td>
<td>
@Html.ValidationMessageFor(x => x.NewComment.Author)
</td>
</tr>
<tr>
<td>
Email:
</td>
<td>
@Html.TextBoxFor(x => x.NewComment.Email)
</td>
<td>
@Html.ValidationMessageFor(x => x.NewComment.Email)
</td>
</tr>
<tr>
<td>
Website:
</td>
<td>
@Html.TextBoxFor(x => x.NewComment.Website)
</td>
<td>
@Html.ValidationMessageFor(x => x.NewComment.Website)
</td>
</tr>
<tr>
<td>
Body:
</td>
<td>
@Html.TextAreaFor(x => x.NewComment.Body)
</td>
<td>
@Html.ValidationMessageFor(x => x.NewComment.Body)
</td>
</tr>
<tr>
<td>
</td>
<td>
<input type="submit" value="Add Comment" />
</td>
</tr>
</table>
</div>
}
操作方法中实现验证?当我发现AddComment
然后是什么?我该怎么回事?此操作方法仅绑定到页面初始Model.IsValid == false
对象的PostComment
属性,因为我不关心该模型上的任何其他属性。
感谢任何帮助。
答案 0 :(得分:2)
您需要重新填充模型并发送到视图。但是,您不需要手动执行此操作,可以使用操作过滤器。
见:
http://weblogs.asp.net/rashid/archive/2009/04/01/asp-net-mvc-best-practices-part-1.aspx#prg
具体做法是:
public abstract class ModelStateTempDataTransfer : ActionFilterAttribute
{
protected static readonly string Key = typeof(ModelStateTempDataTransfer).FullName;
}
public class ExportModelStateToTempData : ModelStateTempDataTransfer
{
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
//Only export when ModelState is not valid
if (!filterContext.Controller.ViewData.ModelState.IsValid)
{
//Export if we are redirecting
if ((filterContext.Result is RedirectResult) || (filterContext.Result is RedirectToRouteResult))
{
filterContext.Controller.TempData[Key] = filterContext.Controller.ViewData.ModelState;
}
}
base.OnActionExecuted(filterContext);
}
}
public class ImportModelStateFromTempData : ModelStateTempDataTransfer
{
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
ModelStateDictionary modelState = filterContext.Controller.TempData[Key] as ModelStateDictionary;
if (modelState != null)
{
//Only Import if we are viewing
if (filterContext.Result is ViewResult)
{
filterContext.Controller.ViewData.ModelState.Merge(modelState);
}
else
{
//Otherwise remove it.
filterContext.Controller.TempData.Remove(Key);
}
}
base.OnActionExecuted(filterContext);
}
}
用法:
[AcceptVerbs(HttpVerbs.Get), ImportModelStateFromTempData]
public ActionResult Index(YourModel stuff)
{
return View();
}
[AcceptVerbs(HttpVerbs.Post), ExportModelStateToTempData]
public ActionResult Submit(YourModel stuff)
{
if (ModelState.IsValid)
{
try
{
//save
}
catch (Exception e)
{
ModelState.AddModelError(ModelStateException, e);
}
}
return RedirectToAction("Index");
}
答案 1 :(得分:0)
在 AddComment ActionResult中,执行以下操作:
if(ModelState.IsValid)
{
// Insert new comment
..
..
// Redirect to a different view
}
// Something is wrong, return to the same view with the model & errors
var postModel = new BlogPostViewModel { PostComment = postComment };
return View(postModel);
答案 2 :(得分:0)
花了很多时间后,我意识到我必须重新填充视图模型并渲染正确的视图,传入完全填充的模型。有点痛,但至少我明白发生了什么。