Symfony - Платформа API - Загрузка файла

Я пытаюсь реализовать загрузку файла с помощью Платформа API после Документация с помощью Vich. Но это не работает, точнее, MediaObject не гидратируется файлом, который я отправляю по моему запросу.

Я в точности следовал кулинарной книге, предоставленной платформой API, но не похоже, что моя форма хорошо обрабатывает запрос, потому что она не проходит проверку ограничения, и я получаю этот ответ от API:

{
    "type": "https://tools.ietf.org/html/rfc2616#section-10",
    "title": "An error occurred",
    "detail": "file: This value should not be null.",
    "violations": [
        {
        "propertyPath": "file",
        "message": "This value should not be null."
        }
    ]
}

Мой запрос базовый: заголовок - multipart / form-data, и я отправляю один небольшой файл (78Ko): "file" => image.jpg

Когда я сбрасываю свой объект $ request, файл находится в нем, но $ form-> getData () не гидратируется. Есть идеи, почему?

Вот мой MediaObject:

namespace App\Entity;

use ApiPlatform\Core\Annotation\ApiProperty;
use ApiPlatform\Core\Annotation\ApiResource;
use App\Traits\updatedAt;
use DateTimeImmutable;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Vich\UploaderBundle\Entity\File;
use Vich\UploaderBundle\Mapping\Annotation as Vich;

/**
 * @ApiResource(iri = "http://schema.org/MediaObject", collectionOperations = {
 *     "get",
 *     "post" = {
 *         "method" = "POST",
 *         "path" = "/media_objects",
 *         "controller"=CreateMediaObjectAction::class,
 *         "defaults" = {"_api_receive"=false},
 *     },
 * })
 * @Vich\Uploadable
 * @ORM\Entity(repositoryClass = "App\Repository\MediaObjectRepository")
 * @ORM\HasLifecycleCallbacks()
 */
class MediaObject
{
    use updatedAt;

    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type = "integer")
     */
    private $id;

    /**
     * @var File|null
     * @Assert\NotNull()
     * @Vich\UploadableField(mapping = "media_object", fileNameProperty = "contentUrl")
     */
    public $file;

    /**
     * @var string|null
     * @ORM\Column(type = "string", length=255, nullable=true)
     * @ApiProperty(iri = "http://schema.org/contentUrl")
     */
    private $contentUrl;

    public function getId(): ?int
    {
        return $this->id;
    }

    public function getFile(): ?string
    {
        return $this->file;
    }

    /**
     * @param string $file
     *
     * @return MediaObject
     * @throws \Exception
     */
    public function setFile(string $file): self
    {
        $this->file = $file;

        if (null !== $file) {
            $this->updatedAt = new DateTimeImmutable();
        }

        return $this;
    }

    public function getContentUrl(): ?string
    {
        return $this->contentUrl;
    }

    public function setContentUrl(?string $contentUrl): self
    {
        $this->contentUrl = $contentUrl;

        return $this;
    }

}

Вот мой Media ObjectType:

namespace App\Form;

use App\Entity\MediaObject;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Vich\UploaderBundle\Form\Type\VichFileType;

class MediaObjectType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            // Configure each fields you want to be submitted here, like a classic form.
            ->add('file', VichFileType::class, [
                'label' => 'label.file',
                'required' => false,
            ])
        ;
    }

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

    public function getBlockPrefix()
    {
        return '';
    }
}

А вот и мой контроллер:

namespace App\Controller;

use ApiPlatform\Core\Bridge\Symfony\Validator\Exception\ValidationException;
use App\Entity\MediaObject;
use App\Form\MediaObjectType;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted;
use Symfony\Bridge\Doctrine\RegistryInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Form\FormFactoryInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Validator\Validator\ValidatorInterface;

final class CreateMediaObjectController extends AbstractController
{
    private $validator;
    private $doctrine;
    private $factory;

    public function __construct(RegistryInterface $doctrine, FormFactoryInterface $factory, ValidatorInterface $validator)
    {
        $this->validator = $validator;
        $this->doctrine  = $doctrine;
        $this->factory   = $factory;
    }

    /**
     * @param Request $request
     * @Route("media_objects", name = "media")
     *
     * @return MediaObject
     */
    public function mediaCreation(Request $request): MediaObject
    {
        $mediaObject = new MediaObject();

        $form = $this->factory->create(MediaObjectType::class, $mediaObject);
        $form->handleRequest($request);
        if ($form->isSubmitted() && $form->isValid()) {

            $em = $this->doctrine->getManager();
            $em->persist($mediaObject);
            $em->flush();

            // Prevent the serialization of the file property
            $mediaObject->file = null;

            return $mediaObject;
        }

        // This will be handled by API Platform and returns a validation error.
        throw new ValidationException($this->validator->validate($mediaObject));
    }
}

Работает ли проверка с Api platfrom?

Vishal Tanna 12.12.2020 05:56
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Symfony Station Communiqué - 17 февраля 2023 г
Symfony Station Communiqué - 17 февраля 2023 г
Это коммюнике первоначально появилось на Symfony Station , вашем источнике передовых новостей Symfony, PHP и кибербезопасности.
Управление ответами api для исключений на Symfony с помощью KernelEvents
Управление ответами api для исключений на Symfony с помощью KernelEvents
Много раз при создании api нам нужно возвращать клиентам разные ответы в зависимости от возникшего исключения.
8
1
4 778
1

Ответы 1

Я использую почтальон и symfony 4.x для этого ответа.

  1. URL-адрес API: localhost / api / media_objects (localhost => baseURL)

  2. Выберите form-data => Ключ должен быть файл и выберите тип File (если вы наведите курсор на правую сторону для ввода, вы увидите раскрывающийся список)

  3. Выберите файл и разместите.

ЗАМЕТКА: у вас должен быть config / packages / vich_uploader.yaml с такими конфигурациями, как

vich_uploader: db_driver: orm

mappings:
    media_object:
        uri_prefix: /media
        upload_destination: '%kernel.project_dir%/public/media'
        namer: Vich\UploaderBundle\Naming\UniqidNamer

Другие вопросы по теме