Публикация из формы в частичном представлении - почему это вызывает неправильное действие контроллера? - PullRequest
3 голосов
/ 03 февраля 2012

Потерпи меня, когда я опишу проблему.

Приложение 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 Частичное представление

@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 Request для /Article/Details/{slug} правильно отображает статью, комментарии и форму редактора.

  2. Редактор работает как задумано, но при нажатии кнопки «Отправить» я заметил, что вызывается действие «Подробности» на моем контроллере, а не действие «Комментарий HttpPost».

Как видите, помощник Razor Form указывает действие Comment на контроллере Article с использованием POST.

Вопрос

Почему это происходит? Чего мне не хватает?

1 Ответ

3 голосов
/ 03 февраля 2012

Chump Award!

Ответ - Маршрутизация.

Если присмотреться к 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" });

Не существует явного маршрута для действия Комментарий. - это универсальный маршрут REST-ish для получения статьи (article/{slug}). Таким образом, комментарий POST обрабатывался им до перехода по маршруту по умолчанию ...

Мое конкретное решение (мне нравится явная маршрутизация - даже когда это доставляет мне неприятности) заключалось в добавлении маршрута для комментариев, как раз для общего шаблона article/{slug}:

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

Проблема решена. Неловко.

...