Symfony REST api-实体关联字段->;值无效
在Symfony中,我正在为Angular2编写一个API。我将FOSRestBundle与JMSSerializerBundle一起使用。现在,我有一个实体“User”,它有一个实体字段“address”,带有一个OneToOne关联。我在保存用户地址时遇到问题 因此,我首先获取用户对象,它返回整个对象,地址为json。然后我把请求和那个完全相同的对象放在一起。在我的PUT函数中,我使用Symfony表单验证数据,然后返回一个错误:Symfony REST api-实体关联字段->;值无效,api,symfony,fosrestbundle,jmsserializerbundle,validationerror,Api,Symfony,Fosrestbundle,Jmsserializerbundle,Validationerror,在Symfony中,我正在为Angular2编写一个API。我将FOSRestBundle与JMSSerializerBundle一起使用。现在,我有一个实体“User”,它有一个实体字段“address”,带有一个OneToOne关联。我在保存用户地址时遇到问题 因此,我首先获取用户对象,它返回整个对象,地址为json。然后我把请求和那个完全相同的对象放在一起。在我的PUT函数中,我使用Symfony表单验证数据,然后返回一个错误: { "children": { "address
{
"children": {
"address": {
"errors": [
"This value is not valid."
]
}
}
}
我的用户实体上还有一些其他字段,当我在表单生成器中省略address字段时,这些字段会保存得很好。顺便说一句:我省略了其他字段,以避免代码量过载
我使用以下版本:
- symfony:3.1
- jms/序列化程序:1.1
- friendsofsymfony/rest捆绑包:2.0
use Doctrine\ORM\Mapping as ORM;
use JMS\Serializer\Annotation as JMS;
/**
* @ORM\Entity
*/
class User
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @ORM\OneToOne(targetEntity="Address", cascade={"persist", "remove"}, orphanRemoval=true)
* @JMS\Type("AppBundle\Entity\Address")
*/
private $address;
地址类别:
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity
*/
class Address
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\Column(type="string")
*/
private $street;
/**
* @ORM\Column(type="string")
*/
private $number;
/**
* @ORM\Column(type="string")
*/
private $postalCode;
/**
* @ORM\Column(type="string")
*/
private $city;
/**
* @ORM\Column(type="string")
*/
private $country;
用户类型类:
use FOS\RestBundle\Form\Transformer\EntityToIdObjectTransformer;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class UserType extends AbstractType
{
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
// Data transformation needed for relationship entities
$addressTransformer = new EntityToIdObjectTransformer($options['em'], 'AppBundle:Address');
$builder
->add($builder->create('address', TextType::class)->addModelTransformer($addressTransformer))
;
}
/**
* @param OptionsResolver $resolver
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\User',
'csrf_protection' => false,
'allow_extra_fields' => true,
'em' => null
));
}
/**
* {@inheritdoc}
*/
public function getName()
{
return 'user';
}
}
UserController类:
use AppBundle\Entity\User;
use AppBundle\Form\UserType;
use FOS\RestBundle\Controller\Annotations as Rest;
use FOS\RestBundle\View\View;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
/**
* Class UserController
* @package AppBundle\Controller
*/
class UserController extends Controller
{
/**
* @Rest\View
* @Route("/users/{id}")
* @Method("PUT")
*/
public function putAction(Request $request, $id)
{
$user = $this->getEntity($id);
$form = $this->createForm(UserType::class, $user, array(
'method' => 'PUT',
'em' => $this->getDoctrine()->getManager()
));
$form->handleRequest($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($user);
$em->flush();
$response = new Response();
$response->setStatusCode(204);
$response->setContent('User saved!');
return $response;
}
return View::create($form, 400);
}
/**
* @Rest\View
* @Route("/users/{id}", requirements={"id": "\d+"})
* @Method("GET")
*/
public function getAction($id)
{
$user = $this->getEntity($id);
return array('user' => $user);
}
/**
* Get the User entity object by the given ID and return it
*
* @param $id
*
* @return User
*/
private function getEntity($id)
{
$user = $this->getDoctrine()->getRepository('AppBundle:User')->find($id);
if (!$user instanceof User) {
throw new NotFoundHttpException('User not found');
}
return $user;
}
我获取并放置的json对象如下所示:
{
"user":
{
"id":1,
"address": {
"id":1,
"street":"Teststreet",
"number":"1",
"postalCode":"9999",
"city":"Citytest",
"country":"Countrytest"
}
}
}
my config.yml:
fos_rest:
param_fetcher_listener: true
body_listener:
array_normalizer: fos_rest.normalizer.camel_keys
format_listener:
rules:
path: ^/
fallback_format: json
prefer_extension: false
priorities: [json, xml]
body_converter:
enabled: false
validate: false
view:
view_response_listener: force
formats:
json: true
xml: true
templating_formats:
html: true
force_redirects:
html: true
failed_validation: HTTP_BAD_REQUEST
default_engine: twig
mime_types:
json: ['application/json', 'application/json;version=1.0', 'application/json;version=1.1']
routing_loader:
default_format: json
serializer:
serialize_null: true
nelmio_api_doc: ~
jms_serializer:
metadata:
directories:
FOSUB:
namespace_prefix: "FOS\\UserBundle"
path: "%kernel.root_dir%/serializer/FOSUserBundle"
我做过类似的事情,我没有在表单类型中使用任何模型转换器。这是我的密码 用户类型:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('address', AddressType::class)
;
}
地址类型:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('street', AddressType::class)
->add('number', AddressType::class)
->add('postalCode', AddressType::class)
// ...
;
}
以及要放置的json对象
{
"user":
{
"address": {
"street":"Teststreet",
"number":"1",
"postalCode":"9999",
"city":"Citytest",
"country":"Countrytest"
}
}
}
我做过类似的事情,我没有在表单类型中使用任何模型转换器。这是我的密码 用户类型:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('address', AddressType::class)
;
}
地址类型:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('street', AddressType::class)
->add('number', AddressType::class)
->add('postalCode', AddressType::class)
// ...
;
}
以及要放置的json对象
{
"user":
{
"address": {
"street":"Teststreet",
"number":"1",
"postalCode":"9999",
"city":"Citytest",
"country":"Countrytest"
}
}
}