recherche

Maison  >  Questions et réponses  >  le corps du texte

La requête Symfony POST réussit la validation mais elle devrait donner une erreur

Modèle de commande.php

<?php

namespace App\Dto\Request\Model;

use Symfony\Component\Validator\Constraints as Assert;

class OrderModel
{
    #[Assert\Uuid(message: "Order id must be an unique identifier value.")]
    #[Assert\Positive(message: "Order id must be a positive integer value.")]
    public int $id;

    /**
     * @Assert\Positive(message="customerId must be a positive integer value.")
     */
    public int $customerId;

    public array $items;

    /**
     * @Assert\Type("string", message="Order total must be a string float value.")
     * @Assert\Type("float", message="Order total must be a string float value.")
     */
    public string $total;
}

Type de commande.php

<?php

use App\Dto\Request\Model\OrderModel;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
use Symfony\Component\Form\Extension\Core\Type\IntegerType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

class OrderType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('id', IntegerType::class)
            ->add('customerId', IntegerType::class)
            ->add('items', CollectionType::class, [
                'entry_type' => ItemType::class
            ])
            ->add('total', TextType::class);
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => OrderModel::class
        ]);
    }
}

OrderController.php :

#[Route('/order', name:'order_new', methods: 'POST')]
public function create(ManagerRegistry $doctrine, Request $request): JsonResponse|Response
{
    $form = $this->createForm(\OrderType::class);
    if ($request->isMethod('POST')) {
        $form->submit($request->request->get($form->getName()));
        if(!$form->isSubmitted() || !$form->isValid()){
            return $this->handleView($this->view($form, Response::HTTP_BAD_REQUEST));
        }
    }
}

Ma demande de publication :

{
  "id": "dsdas",
  "customerId": 1,
  "items": [
      {
          "productId": 1,
          "quantity": 1,
          "unitPrice": "250.25",
          "total": "250.25"
      },
      {
          "productId": 1,
          "quantity": 1,
          "unitPrice": "250.25",
          "total": "250.25"
      }
  ],
  "total": "500.50"
}

Cette demande est en cours de vérification et j'essaie de la comprendre. Toutes les idées seraient grandement appréciées.

P粉231079976P粉231079976246 Il y a quelques jours432

répondre à tous(1)je répondrai

  • P粉327903045

    P粉3279030452024-03-30 12:25:10

    Je pense qu'il vous manque le nom du formulaire comme clé de niveau supérieur dans les données soumises. Vous essayez d'envoyer ceci :

    {
        "id": "dsdas",
        "customerId": 1,
        "total": "500.50"
    }

    Votre code ($request->request->get($form->getName())) s'attend à cela (si le nom du formulaire est "order_type")

    {
        "order_type": {
            "id": "dsdas",
            "customerId": 1,
            "total": "500.50"
        }
    }

    Une solution consiste à créer un formulaire nommé...sans nom :)

    public function create(
        Request $request,
        FormFactoryInterface $formFactory
    ) {
        // Create form with no name: setting the first parameter to '' means no name (ideal for API endpoints)
        $form = $formFactory->createNamed('', OrderType::class);
        $form->handleRequest($request);
        if(
            !$form->isSubmitted() ||
            !$form->isValid()
        ) {
            // ...
        } else {
            // ...
        }
    }

    La deuxième solution consiste à ajouter vous-même le nom du formulaire

    public function create(Request $request): JsonResponse|Response
    {
        $form = $this->createForm(\OrderType::class);
        if ($request->isMethod('POST')) {
            $form->submit([
                // You can also add the key yourself right before submitting
                $form->getName() => $request->request->all(),
            ]);
            if(
                !$form->isSubmitted() ||
                !$form->isValid()
            ){
                return $this->handleView($this->view($form, Response::HTTP_BAD_REQUEST));
            }
        }
    }

    La troisième option (mais pas la meilleure) est que vous envoyez toujours les données au contrôleur avec la clé du formulaire, mais je ne choisirais pas cette option s'il s'agissait d'un point de terminaison d'API. Donc seulement s'il s'agit d'une soumission de formulaire régulière et que les champs du formulaire soumis sont tous générés avec le préfixe du nom du formulaire d'origine.

    En dernière option, vous pouvez également capturer les données entrantes dans les deux formats. Peut-être quelque chose comme ça et vous pouvez réellement envoyer avec ou sans clé :

    $finalData = $request->request->get($form->getName()) ?: $request->request->all();
    $form->submit([$form->getName() => $finalData]);

    répondre
    0
  • Annulerrépondre