2010-01-10 2 views
5

Моя установка:Следует ли использовать RenderAction с формами?

  • имеют вид на маршрут, как: /Pages/Details/2
  • Детали страницы просмотра имеет <% Html.RenderAction("CreatePageComment", "Comments"); %>, чтобы сделать форму для написания комментария
  • сообщения Комментарий формы для Comments/CreatePageComment
  • /Comments/CreatePageComment возвращается RedirectToAction когда комментарий успешно создан
  • Все это прекрасно работает

Мой вопрос:

Если ошибка проверки, как я должен вернуться к /Pages/Detail/1 и показать ошибку в форме комментария?

  • Если я использую RedirectToAction, кажется, проверка достоверна; должен ли я использовать шаблон Post-Redirect-Get для ошибок проверки, а не просто вернуться?
  • Если я вернусь View(), он возвращает меня обратно к показу CreateComment.aspx (с проверкой, но только форма на белой странице), а не маршрут /Pages/Details/2, который называется RenderAction.

Если шаблон PRG должен использоваться, тогда, я думаю, мне просто нужно научиться валидации при использовании PRG. Если не —, и для меня это кажется лучше обработанным возвратом View() —, то я не знаю, как вернуть пользователя в исходное представление, показывая ошибки формы, используя RenderAction.

Это похоже на игру, в которой вы постукиваете головой и втираете живот в одно и то же время. Я тоже не был хорош в этом. Я новичок в MVC, так что, скорее всего, проблема здесь.

+0

BTW: Я мог бы сделать это, просто используя Partial и POST route/Page/CreateComment, но разве это не беспорядочно? Я хочу, чтобы мои комментарии контроллера обрабатывали комментарии, а не контроллер страницы. Как ни странно, я только что просмотрел код двигателя блога Oxite, и их контроллер Post обрабатывает добавление комментариев; их контроллер комментариев даже не имеет действия «Создать»! –

ответ

5

Я считаю, что ответ заключается в использовании TempData, например:

На мой взгляд (/ Steps/Детали) У меня есть:

<!-- List comments --> 
<% Html.RenderAction("List", "Comments", new { id = Model.Step.Id }); %> 

<!-- Create new comment --> 
<% Html.RenderAction("Create", "Comments", new { id = Model.Step.Id }); %> 

В моем комментарии контроллер У меня есть метод POST:

// POST: /Comments/Create 
    [HttpPost] 
    public ActionResult Create([Bind(Exclude = "Id, Timestamp, ByUserId, ForUserId")]Comment commentToCreate) 
    { 
     if (ModelState.IsValid) 
     { 
      //Insert functionality here 

      return RedirectToAction("Details", "Steps", new { id = commentToCreate.StepId }); 

     } 

    //If validation error 
     else 
     { 

      //Store modelstate from tempdata 
      TempData.Add("ModelState", ModelState); 

      //Redirect to action (this is hardcoded for now) 
      return RedirectToAction("Details", "Steps", new { id = commentToCreate.StepId }); 
     } 
    } 

Кроме того, в контроллер комментарии мой метод GET:

// 
    // GET: /Comments/Create 

    public ActionResult Create(int id) 
    { 

     if (TempData.ContainsKey("ModelState")) 
     { 
      ModelStateDictionary externalModelState = (ModelStateDictionary)TempData["ModelState"]; 
      foreach (KeyValuePair<string, ModelState> valuePair in externalModelState) 
      { 
       ModelState.Add(valuePair.Key, valuePair.Value); 
      } 
     } 
     return View(new Comment { StepId = id }); 
    } 

Это прекрасно работает для меня, но я оценил бы обратную связь по этому вопросу, является ли хорошей практикой, и т.д.

Кроме того, я заметил, что MvcContrib имеет украшение ModelStateToTempData, который появляется, чтобы сделать это, но более чистым способом , Я собираюсь попробовать это дальше.

+0

У меня была аналогичная проблема с тем, что у вас было. Решение, которое вы предлагаете, похоже, работает, но мне любопытно, нет ли более чистого способа сделать это. Для меня ваше решение кажется скорее взломом, чем реальным решением. Я не знаю, есть ли у кого-нибудь другое мнение по этому поводу? – Melursus

+0

Да, он чувствует себя хакерским, но это все, что я мог найти, что работает. Как и вы, я бы приветствовал более чистое решение. –

+0

В моем исследовании я обнаружил, что в библиотеке MvcContrib есть что-то, называемое SubController, которое может решить эту проблему. Я не смотрю дальше, но это кажется интересным. – Melursus