Пользовательский контроллер DXA, потерявший MvcData на HttpPost


2

У меня есть пользовательский контроллер формы в веб-приложении DXA 1.2, который работает нормально во время запроса, но когда я отправляю данные формы обратно этому контроллеру и возвращаю Entity DXA, выдает ошибку как он потерял MvcData для моего настраиваемого контроллера.

ERROR - Error executing child request for handler 'System.Web.Mvc.HttpHandlerUtil+ServerExecuteHttpHandlerAsyncWrapper'. 
System.Web.HttpException (0x80004005): Error executing child request for handler 'System.Web.Mvc.HttpHandlerUtil+ServerExecuteHttpHandlerAsyncWrapper'. ---> System.InvalidOperationException: The view 'Index' or its master was not found or no view engine supports the searched locations. The following locations were searched: 
~/Views/Form/Index.aspx 
~/Views/Form/Index.ascx 
~/Views/Shared/Index.aspx 
~/Views/Shared/Index.ascx 
~/Views/Form/Index.cshtml 
~/Views/Form/Index.vbhtml 
~/Views/Shared/Index.cshtml 
~/Views/Shared/Index.vbhtml 
    at System.Web.Mvc.ViewResult.FindView(ControllerContext context) 

код контроллера:

public class FormController : EntityController 
{ 
    [HandleSectionError(View = "SectionError")] 
    public ActionResult Index(EntityModel entity, int containerSize = 0) 
    { 
     // The List action is effectively just an alias for the general Entity action (we keep it for backward compatibility). 
     return Entity(entity, containerSize); 
    } 

    [HttpPost] 
    public ActionResult Index(Form form) 
    { 
     //do stuff here and modify the success flag 
     form.SubmittedSuccessfully = true; 
     return Entity(form); 
    } 
} 

Есть в любом случае, чтобы повторно заполнить эти данные?

  0

Можете ли вы объяснить, чего вы пытаетесь достичь с помощью контроллера формы? Обратите внимание, что контроллеры сущностей DXA не являются обычными контроллерами; они являются своего рода субконтроллерами, которые обычно вызывается из представления Page/Region с помощью метода Html.DxaEntity. 17 фев. 162016-02-17 18:24:16

  0

Кстати, вам не нужно действие/метод индекса. Кажется, что реализация была скопирована из ListController, но, как говорится в комментарии, ListController имеет только обратную совместимость. 17 фев. 162016-02-17 19:00:14

  0

Это простая форма, которая отправляет себе сообщение, которое отправит электронное письмо с данными формы, а затем изменит данные модели, если письмо было успешным или нет. 17 фев. 162016-02-17 19:29:39

2

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

protected override ViewModel EnrichModel(ViewModel model) 
{ 
    var form = model as Form; 
    TempData["MvcData"] = form.MvcData; 
    return base.EnrichModel(model); 
} 

Затем форма контроллер поднимает штангу, а затем я заново создайте MvcData, используя значение в TempData

[HttpPost] 
[ValidateAntiForgeryToken] 
public ActionResult Index(Form form) 
{ 
    form.MvcData = TempData["MvcData"] as MvcData; 
    //do some business logic here 
    form.SubmittedSuccessfully = true; 
    return Entity(form); 
} 
+2

Ой! Это довольно неуверенно. (Я не вижу 'ValidateAntiForgeryToken'). Может быть, 'TempData' - лучшая альтернатива? Задайте его в исходном методе «Индекс», прочитайте его в опубликованном методе «Индекс» (и установите его снова там, если он вам понадобится). Например: TempData ["mvc-data"] = MvcData; 23 фев. 162016-02-23 12:28:24

  0

Я согласен с ouch!Я добавил дополнительную безопасность, но не хотел публиковать весь код. Я посмотрю параметр TempData. 23 фев. 162016-02-23 13:20:44

+1

Обновление кода выше Альберта, поскольку ваша идея использовать TempData лучше 23 фев. 162016-02-23 15:15:37


1

Самый простой способ добиться того, что вы хотите, это позволить форме отправить себя с использованием HTTP GET в URL-адрес страницы, содержащей форму.

Таким образом, встроенный Контроллер страницы будет обрабатывать форму submit (PageController.Page). Он делегирует свою работу региональным контроллерам и контроллерам сущностей. Если одним из объектов на странице является форма (с соответствующим FormController), будет вызван метод FormController.EnrichModel.

Итак, вы должны переопределить метод EnrichModel в Контроллере форм, и там у вас будет доступ к данным формы (в параметрах строки запроса). См., Например, переопределение ListController.EnrichModel.

Если вам действительно нужно использовать HTTP POST, я думаю, что встроенный метод PageController.Page не может быть использован. В этом случае вам придется создать свой собственный (Page) контроллер и дать ему аналогичную реализацию, как PageController.Page. Я бы рекомендовал, чтобы ваш контроллер наследовал от PageController, и пусть ваш метод действия делегирует PageController.Page.

  0

. Форма должна быть сообщением, поскольку я не хочу, чтобы все данные появляющиеся в строках запроса. Мне также нужно, чтобы это было Entity, чтобы редактор содержимого мог добавлять свою форму на любую страницу на веб-сайте? 18 фев. 162016-02-18 08:55:17

  0

Кажется, лучший способ сохранить функциональность Post - отобразить MvcData на скрытые поля @ Html.HiddenFor (x => x.MvcData.ActionName), а затем они отображаются в объект Form, когда все данные формы отправляются , 18 фев. 162016-02-18 09:41:24

  0

В целом, я не хочу, чтобы вы отправляли сообщение в контроллер сущности и позволяли ему возвращать Entity в изоляции; вы хотите получить страницу как ответ, правильно? Итак, вы должны отправить сообщение в Контроллер страницы, который возвращает страницу, которая может содержать объект формы. 18 фев. 162016-02-18 19:42:56