从部分视图中的表单发布 - 为什么它会触发错误的控制器操作?

时间:2012-02-03 19:18:55

标签: c# html asp.net-mvc post razor

在描述问题时请耐心等待。

使用部分视图的MVC3应用程序。无法在其父模型的“详细信息”视图的部分视图中发布“评论”表单。

供参考ArticleViewModel有一个CommentsViewModel的集合,因此存在OTM关系。

详细信息视图

@model ArticleViewModel

// Renders the Article and its Comments - no forms, just display markup
// A nested _Comments partial is used to render the article's comments.
@Html.Partial("_Article", Model)

// Renders HTML and Javascript for the Pagedown editor - POST form inside.
@Html.Partial("_CommentEditor", new CommentViewModel())

@section scripts { /* code here for validation and the javascript editor */ }

_CommentEditor Partial View

@model CommentViewModel

@using (Html.BeginForm("Comment","Article",FormMethod.Post)) {
    @Html.TextAreaFor(m => m.Content)
    <input type="submit" value="Submit" />
    <input type="reset" value="Clear" />    
}

物品管理员

public ActionResult Details(string slug) {
    return View(_articleService.Get(slug));
}

[HttpPost]
public ActionResult Comment(string slug, CommentViewModel comment) {
    if(ModelState.IsValid) {
        _articleService.AddComment(comment, slug);
    }
    return RedirectToAction("Details", new { Slug = slug });
}

场景/问题

  1. Http /Article/Details/{slug}请求正确呈现文章,评论和编辑表格。

  2. 编辑器按预期工作,但点击提交时,我注意到我的控制器上的详细信息操作被调用而不是HttpPost评论操作。

  3. 正如您所见,Razor Form帮助器使用Comment指定Article控制器上的POST操作。

    问题

    为什么会这样?我错过了什么?

1 个答案:

答案 0 :(得分:2)

笨蛋奖!

答案是路由。

与Fiddler仔细观察,我实际上是向POST发送/article/comment请求,所以我检查了我的路由...我怎么错过了这个,我不知道:

routes.MapRoute("Article-Create", "article/create", new { controller = "Article", action = "Create" });
routes.MapRoute("Article-Edit", "article/edit/{slug}", new { controller = "Article", action = "Edit" });
routes.MapRoute("Article-Delete", "article/delete/{slug}", new { controller = "Article", action = "Delete" });
routes.MapRoute("Article", "article/{slug}", new { controller = "Article", action = "Details" });
routes.MapRoute("Articles", "articles", new { controller = "Article", action = "Index" });

评论操作没有明确的路线。 是一个用于获取文章(article/{slug})的全能REST-ish路由。因此,在点击默认路由之前,它正在处理评论POST ...

我的具体解决方案(我喜欢显式路由 - 即使它让我遇到麻烦)是添加注释路由,只是关于全能article/{slug}模式:

routes.MapRoute("Article-Comment", "article/comment", new { controller = "Article", action = "Comment" });

问题解决了。尴尬。