我正在尝试通过复杂的表单提交JSON。我不知道我想念的是什么。 “正常”形式正在起作用。我可以按组获取序列化的数据。
Class TaskBoard
class TaskBoard
{
/**
* @var integer $id id
*
* @ORM\Id()
* @ORM\GeneratedValue(strategy="AUTO")
* @ORM\Column(type="integer")
*/
private $id;
/**
* @var \DateTime $createdTime createdTime
*
* @ORM\Column(type="datetime")
* @Assert\DateTime()
*/
private $createdTime;
/**
* @var \DateTime $lastUpdatedTime lastUpdatedTime
*
* @ORM\Column(type="datetime", nullable=true)
* @Assert\DateTime()
*/
private $lastUpdatedTime;
/**
* @var string $name name
*
* @ORM\Column(type="string", length=20)
* @Assert\Type("string")
* @Assert\NotBlank()
* @Assert\Length(
* min = 2,
* max = 20,
* minMessage = "The name must be at least {{ limit }} characters long",
* maxMessage = "The name cannot be longer than {{ limit }} characters"
* )
*/
private $name;
/**
* @var App\Entity\User $user user
*
* @ORM\ManyToOne(targetEntity="App\Entity\User", inversedBy="taskboards", cascade={"persist"})
* @ORM\JoinColumn(name="user_id", referencedColumnName="id")
*/
private $user;
/**
* @var string $description description
*
* @ORM\Column(type="text", nullable=true)
* @Assert\Type("string")
*/
private $description;
/**
* @var App\Entity\Status $status status
*
* @ORM\ManyToOne(targetEntity="App\Entity\Status", inversedBy="taskboards", cascade={"persist"})
* @ORM\JoinColumn(name="status_id", referencedColumnName="id", nullable=false)
*/
private $status;
/**
* @var boolean $completed completed
*
* @ORM\Column(type="boolean")
*/
private $completed;
/**
* @var \DateTime $deadLine deadLine
*
* @ORM\Column(type="date", nullable=true)
* @Assert\DateTime()
* @Assert\GreaterThanOrEqual("today")
*/
private $deadLine;
课程状态
class Status
{
/**
* @ORM\Id()
* @ORM\GeneratedValue(strategy="AUTO")
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\Column(type="string", length=20)
*/
private $name;
/**
* @ORM\OneToMany(targetEntity="App\Entity\TaskBoard", mappedBy="status", cascade={"persist"})
*/
public $taskboards;
班级用户
class User extends BaseUser
{
/**
* @ORM\Id()
* @ORM\GeneratedValue(strategy="AUTO")
* @ORM\Column(type="integer")
*/
protected $id;
/**
* @ORM\OneToMany(targetEntity="App\Entity\TaskBoard", mappedBy="user", cascade={"persist"})
*/
public $taskboards;
表格
class TaskBoardType extends AbstractType {
public function buildForm(FormBuilderInterface $builder, array $options) {
$builder
->add('name', TextType::class)
->add('user', EntityType::class, array(
'class' => User::class,
'choice_label' => 'username',
)
)
->add('description', TextareaType::class, array(
'required' => false
))
->add('status', EntityType::class, array(
'class' => Status::class,
'choice_label' => 'name',
)
)
->add('deadLine', DateTimeType::class)
;
}
public function configureOptions(OptionsResolver $resolver) {
$resolver->setDefaults([
'data_class' => TaskBoard::class,
'csrf_protection' => false,
]);
}
控制器
class TaskBoardAPIController extends AbstractController {
public function postTaskBoard(Request $request) {
$form = $this->createForm(TaskBoardType::class, new TaskBoard());
$data = json_decode(
$request->getContent(), true
);
var_dump($data);
$form->submit($data);
if (!$form->isValid()) {
return new JsonResponse(
[
'status' => 'error',
'errors' => $form->getErrors(),
'form' => $form,
], JsonResponse::HTTP_BAD_REQUEST
);
}
$this->entityManager->persist($form->getData());
$this->entityManager->flush();
return new JsonResponse(
[
'status' => 'ok',
], JsonResponse::HTTP_CREATED
);
}
已发送JSON
{
"name": "XXX",
"user": {
"id": 1,
"username": "BFA"
},
"description": "XXXXXXXXXXXXXXX",
"status": {
"id": 1,
"name": "To Do"
},
"completed": false
}
该表单无效,并且在JsonResponse中为空白。
我基于:https://codereviewvideos.com/course/beginners-guide-back-end-json-api-front-end-2018/video/symfony-4-json-api-form-submission 和Deserialize an entity with a relationship with Symfony Serializer Component
感谢您的帮助。
答案 0 :(得分:0)
您忘记处理并提交表单了。 请注意,您将需要使用类似
的方法获取请求数据 $form = $this->createFormBuilder($task)
... add fields
->getForm();
$form->handleRequest($request); // handling request
if ($form->isSubmitted() && $form->isValid()) {
// $form->getData() holds the submitted values
// but, the original `$task` variable has also been updated
$task = $form->getData();
// ... perform some action, such as saving the task to the database
// for example, if Task is a Doctrine entity, save it!
// $entityManager = $this->getDoctrine()->getManager();
// $entityManager->persist($task);
// $entityManager->flush();
return $this->redirectToRoute('...');
}
有关更多信息,请参见Handling Form Submissions
答案 1 :(得分:0)
出问题的是JSON输入。
表单执行此操作:
class TaskBoardType extends AbstractType {
public function buildForm(FormBuilderInterface $builder, array $options) {
$builder
->add('name', TextType::class)
->add('user', EntityType::class, array(
'class' => User::class,
'choice_label' => 'username',
)
)
->add('description', TextareaType::class, array(
'required' => false
))
->add('status', EntityType::class, array(
'class' => Status::class,
'choice_label' => 'name',
)
)
->add('deadLine', DateTimeType::class)
;
}
public function configureOptions(OptionsResolver $resolver) {
$resolver->setDefaults([
'data_class' => TaskBoard::class,
'csrf_protection' => false,
]);
}
检查从表单生成的代码时,结果如下:
<div>
<label for="task_board_user" class="required">User</label>
<select id="task_board_user" name="task_board[user]">
<option value="1">XXX</option>
<option value="2">XXX</option>
</select>
</div>
因此表单直接需要一个INT / ID。
通过如下更改JSON来进行验证:
{
"name": "XXXO",
"user": 1,
"description": "XXXXXXXXXXXXXXX",
"status": 1
}