You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 20:27:07