我在后端有一个Symfony 4的React应用程序,抛出上述异常。
我尝试关注this post(法语)。
在Symfony的探查器Form上,我可以看到两个文件,每个文件都有自己的错误。摘录如下:
This value is not valid. 0 Caused by:
ConstraintViolation {#993 ▼
root: Form {#792 ▶}
path: "children[attachments].children[0]"
value: UploadedFile {#36 ▼
-test: false
-originalName: "alfa-romeo-4C-1.jpg"
-mimeType: "image/jpeg"
-error: 0
path: "/Applications/MAMP/tmp/php"
filename: "php0vUzd5"
basename: "php0vUzd5"
pathname: "/Applications/MAMP/tmp/php/php0vUzd5"
....
}
}
TransformationFailedException {#1029 ▼
#message: "Compound forms expect an array or NULL on submission."
....
感谢您的帮助。
在React中,我使用formData和以下代码:
let formData = new FormData();
formData.append('message[message]', this.props.message_form.values.message.message);
formData.append('message[ad]', this.props.match.params.ad_id);
// insert files in formData, if any
if (this.state.selectedFile.length > 0) {
const file_length = this.state.selectedFile.length;
for (let i = 0; i < file_length; i++) {
formData.append('message[attachments][]', this.state.selectedFile[i]);
}
}
这似乎正确发送了数据。检查$ _FILES转储会得到如下内容,这与我能看到的here一致。
["message"]=> array(5) {
["name"]=> array(1) {
["attachments"]=> array(2) {
[0]=> string(19) "alfa-romeo-4C-1.jpg"
[1]=> string(19) "alfa-romeo-4C-3.jpg" } }
["type"]=> array(1) {
["attachments"]=> array(2) {
[0]=> string(10) "image/jpeg"
[1]=> string(10) "image/jpeg" } }
["tmp_name"]=> array(1) {
["attachments"]=> array(2) {
[0]=> string(36) "/Applications/MAMP/tmp/php/phppPLE3Z"
[1]=> string(36) "/Applications/MAMP/tmp/php/phpAF1yQZ" } }
["error"]=> array(1) {
["attachments"]=> array(2) {
[0]=> int(0)
[1]=> int(0) } }
["size"]=> array(1) {
["attachments"]=> array(2) {
[0]=> int(41024)
[1]=> int(76577) } }
} }
消息实体:
class Message{
... other properties
/**
* @ORM\OneToMany(targetEntity="App\Entity\Attachment", mappedBy="message",cascade="all", orphanRemoval=true)
* @Assert\Valid()
* @Assert\NotNull()
*/
private $attachments;
public function __construct()
{
$this->attachments = new ArrayCollection();
}
... other methods
/**
* @return Collection|Attachment[]
*/
public function getAttachments(): Collection
{
return $this->attachments;
}
public function addAttachment(Attachment $attachment): self
{
if (!$this->attachments->contains($attachment)) {
$this->attachments[] = $attachment;
$attachment->setMessage($this);
}
return $this;
}
public function removeAttachment(Attachment $attachment): self
{
if ($this->attachments->contains($attachment)) {
$this->attachments->removeElement($attachment);
// set the owning side to null (unless already changed)
if ($attachment->getMessage() === $this) {
$attachment->setMessage(null);
}
}
return $this;
}
附件实体:
class Attachment
{
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\ManyToOne(targetEntity="App\Entity\Message", inversedBy="attachments")
* @ORM\JoinColumn(nullable=false)
* @Assert\NotNull()
*/
private $message;
/**
* @ORM\Column(type="string", length=255, nullable=true)
* @Assert\File(mimeTypes={ "image/jpeg" })
* @Assert\NotNull()
*/
private $path;
/**
* Constructor
*
* @param Message $message
*/
public function __construct(Message $message = null)
{
$this->message = $message;
}
public function getId()
{
return $this->id;
}
public function getMessage(): ?Message
{
return $this->message;
}
public function setMessage(?Message $message): self
{
$this->message = $message;
return $this;
}
public function getPath()
{
return $this->path;
}
public function setPath($path)
{
$this->path = $path;
return $this;
}
}
MessageType:
$builder
->add('message', TextType::class)
->add('ad', EntityType::class, array(
'class' => Ad::class,
))
->add('attachments', CollectionType::class,array(
'entry_type' => AttachmentType::class,
'allow_add' => true,
'allow_delete' => true,
'by_reference' => false,
));
附件类型:
$builder
->add('path', FileType::class, array(
'multiple' => true,
))
->add('message', TextType::class, array('label' => 'file'));
最后是MessageController:
private function insertMessage ($request) {
$message = new Message();
$form = $this->createForm('App\Form\MessageType', $message);
// get message object and place it as form message content
$data = $request->request->all();
$text = $data['message']['message'];
$message->setMessage($text);
// get/set ad object
$new_ad = new Ad();
$ad = $this->ad_repo->findOneById($data['message']['ad']);
if ($ad instanceof $new_ad) {
$message->setAd($ad);
}
//set sender
isset($this->user) ?
$message->setSender($this->user) :
false;
// get/set receiver
$receiver_id = $ad->getUser();
$receiver = $this->userManager->findUserBy(array('id'=>$receiver_id));
$message->setReceiver($receiver);
$form->handleRequest($request); // that's where the exception is thrown
答案 0 :(得分:0)
我遇到了几个问题:
在客户端,数组的格式应为:
let formData = new FormData();
formData.append('message[message]', this.props.message_form.values.message.message);
formData.append('message[ad]', this.props.match.params.ad_id);
// insert files in formData, if any
if (this.state.selectedFile.length > 0) {
const file_length = this.state.selectedFile.length;
for (let i = 0; i < file_length; i++) {
const unique = `message[attachments][${i}][path]`;
formData.append(unique, this.state.selectedFile[i]);
}
}
AttachmentType应该如下所示:
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\FileType;
use Symfony\Component\Validator\Constraints\File;
.....
$builder
->add('path', FileType::class, array(
'constraints' => array(
new File(),
),
));