TYPO3 11.5:控制器动作中如何获取验证失败的域对象属性?
TYPO3 Extbase验证失败后获取提交对象的解决方案
当sendOrderAction验证失败重定向回formAction时,Extbase默认不会保留提交的Order对象数据,即便添加@IgnoreValidation注解也无法直接通过参数获取对象,以下是几种可行的解决方法:
方法1:通过FlashMessage传递必要属性
验证失败时,将需要保留的属性存入FlashMessage附加数据,在formAction中提取并复用:
修改sendOrderAction
/** * sendOrder action * * @param Order $order * @throws \TYPO3\CMS\Extbase\Mvc\Exception\StopActionException */ public function sendOrderAction(Order $order): void { try { $this->orderRepository->add($order); $this->persistenceManager->persistAll(); $this->addFlashMessage('订单提交成功', '成功', \TYPO3\CMS\Core\Messaging\AbstractMessage::SUCCESS); $this->redirect('form'); } catch (\TYPO3\CMS\Extbase\Validation\Exception\ValidationFailedException $e) { // 存入需要保留的订单属性 $this->getFlashMessageQueue()->enqueue( new \TYPO3\CMS\Core\Messaging\FlashMessage( '', '', \TYPO3\CMS\Core\Messaging\AbstractMessage::ERROR, true, ['orderData' => [ 'firstName' => $order->getFirstName(), 'lastName' => $order->getLastName() ]] ) ); $this->redirect('form'); } }
修改formAction
/** * form action * * @param Order $order * @TYPO3\CMS\Extbase\Annotation\IgnoreValidation("order") * * @return void */ public function formAction(Order $order = null): void { // 从FlashMessage提取订单数据 foreach ($this->getFlashMessageQueue()->getAllMessages() as $message) { $additionalData = $message->getAdditionalData(); if (isset($additionalData['orderData'])) { $orderData = $additionalData['orderData']; // 初始化Order对象并赋值属性 if (empty($order)) { $order = $this->objectManager->get(Order::class); $order->setFirstName($orderData['firstName']); $order->setLastName($orderData['lastName']); } break; } } // 现在可正常访问$order属性 if ($order !== null) { DebuggerUtility::var_dump($order->getFirstName()); } $this->view->assign('order', $order); }
方法2:用Session存储完整对象
如果需要保留整个Order对象,可存入Extbase Session:
控制器注入Session
/** * @var \TYPO3\CMS\Extbase\Persistence\Generic\Session * @inject */ protected $session;
修改sendOrderAction
public function sendOrderAction(Order $order): void { try { $this->orderRepository->add($order); $this->persistenceManager->persistAll(); $this->addFlashMessage('订单提交成功', '成功', \TYPO3\CMS\Core\Messaging\AbstractMessage::SUCCESS); $this->session->remove('failedOrder'); $this->redirect('form'); } catch (\TYPO3\CMS\Extbase\Validation\Exception\ValidationFailedException $e) { $this->session->set('failedOrder', $order); $this->redirect('form'); } }
修改formAction
/** * form action * * @param Order $order * @TYPO3\CMS\Extbase\Annotation\IgnoreValidation("order") * * @return void */ public function formAction(Order $order = null): void { $failedOrder = $this->session->get('failedOrder'); if ($failedOrder instanceof Order) { $order = $failedOrder; $this->session->remove('failedOrder'); } if ($order !== null) { DebuggerUtility::var_dump($order->getFirstName()); } $this->view->assign('order', $order); }
方法3:验证失败直接渲染Form视图
跳过重定向,在sendOrderAction验证失败时直接渲染form视图,直接传递Order对象:
/** * sendOrder action * * @param Order $order */ public function sendOrderAction(Order $order): void { try { $this->orderRepository->add($order); $this->persistenceManager->persistAll(); $this->addFlashMessage('订单提交成功', '成功', \TYPO3\CMS\Core\Messaging\AbstractMessage::SUCCESS); $this->redirect('form'); } catch (\TYPO3\CMS\Extbase\Validation\Exception\ValidationFailedException $e) { // 直接渲染form模板并传递对象 $this->view->setTemplate('Form'); $this->view->assign('order', $order); // 保留验证错误信息 $this->arguments->getArgument('order')->setValidationResults($e->getValidationResults()); } }
各方法优缺点
- 方法1:适合仅需部分属性的场景,数据量小,无Session依赖,但需手动提取属性。
- 方法2:适合需要完整对象的场景,但需注意Session生命周期,避免数据残留。
- 方法3:最直接,无需额外存储,但URL不会切换回
formAction,刷新页面会重新提交表单。
内容的提问来源于stack exchange,提问作者biedert
相关产品推荐
相关产品推荐

