我正在尝试使用此文档设置上传到 API 平台服务器:
https://api-platform.com/docs/core/file-upload/
但是,在尝试使用curl 上传时,遵循所有这些步骤会出现错误。
curl -k -X POST -H "Content-Type: multipart/form-data" -F "file=@/XXXXX/something.png" https://localhost/media_objects
{
"@context":"/contexts/Error",
"@type":"hydra:Error",
"hydra:title":"An error occurred",
"hydra:description":"The class \u0022App\Entity\MediaObject\u0022 is not uploadable. If you use attributes to configure VichUploaderBundle, you probably just forgot to add #[Vich\\Uploadable] on top of your entity. If you don\u0027t use attributes, check that the configuration files are in the right place. In both cases, clearing the cache can also solve the issue."
}
......
重要部分:
类 \u0022App\Entity\MediaObject\u0022 不可上传。如果您使用属性来配置 VichUploaderBundle,您可能只是忘记在实体顶部添加 #[Vich\Uploadable]。如果您不使用属性,请检查配置文件是否位于正确的位置。对于这两种情况,清除缓存也可以解决问题。
我的代码完全来自 API Platform 的示例:
<?php
// api/src/Entity/MediaObject.php
namespace App\Entity;
use ApiPlatform\Metadata\ApiProperty;
use ApiPlatform\Metadata\ApiResource;
use ApiPlatform\Metadata\Get;
use ApiPlatform\Metadata\GetCollection;
use ApiPlatform\Metadata\Post;
use ApiPlatform\OpenApi\Model;
use App\Controller\CreateMediaObjectAction;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\HttpFoundation\File\File;
use Symfony\Component\Serializer\Annotation\Groups;
use Symfony\Component\Validator\Constraints as Assert;
use Vich\UploaderBundle\Mapping\Annotation as Vich;
#[Vich\Uploadable]
#[ORM\Entity]
#[ApiResource(
normalizationContext: ['groups' => ['media_object:read']],
types: ['https://schema.org/MediaObject'],
operations: [
new Get(),
new GetCollection(),
new Post(
controller: CreateMediaObjectAction::class,
deserialize: false,
validationContext: ['groups' => ['Default', 'media_object_create']],
openapi: new Model\Operation(
requestBody: new Model\RequestBody(
content: new \ArrayObject([
'multipart/form-data' => [
'schema' => [
'type' => 'object',
'properties' => [
'file' => [
'type' => 'string',
'format' => 'binary'
]
]
]
]
])
)
)
)
]
)]
class MediaObject
{
#[ORM\Id, ORM\Column, ORM\GeneratedValue]
private ?int $id = null;
#[ApiProperty(types: ['https://schema.org/contentUrl'])]
#[Groups(['media_object:read'])]
public ?string $contentUrl = null;
#[Vich\UploadableField(mapping: "media_object", fileNameProperty: "filePath")]
#[Assert\NotNull(groups: ['media_object_create'])]
public ?File $file = null;
#[ORM\Column(nullable: true)]
public ?string $filePath = null;
public function getId(): ?int
{
return $this->id;
}
}
正如您可以清楚地看到的,我们拥有正确的属性并包括:
use Vich\UploaderBundle\Mapping\Annotation as Vich;
#[Vich\Uploadable]
我们的 VICH yaml 配置设置为使用属性:
vich_uploader:
db_driver: orm
metadata:
type: attribute
mappings:
media_object:
uri_prefix: /media
upload_destination: '%kernel.project_dir%/public/media'
# Will rename uploaded files using a uniqueid as a prefix.
namer: Vich\UploaderBundle\Naming\OrignameNamer
那么为什么我会收到错误消息?我该如何解决这个问题?
VICH Bundle 和 Doctrine 2.8+ 有一个陷阱
使用 Doctrine-bundle >= 时需要 Doctrine/annotations 包 2.8 如果您的项目使用doctrine-bundle:>=2.8,您必须从您的项目中获取doctrine/annotations包,因为它不是必需的 从这个版本开始,不再在学说捆绑中。该捆绑包使用的是 此包中的阅读器接口可同时用于两者 注释和属性映射。
所以就我而言,解决方案只是将
doctrine-annotations
包包含在我的 docker api 平台实现中:
docker compose exec php composer require doctrine/annotations
我通过将元数据类型显式设置为属性解决了这个问题。
vich_uploader:
metadata:
type: attribute