Question

I am sending an AJAX POST with JSON data to a Symfony2 controller. Without any data specified, the controller does create an empty record and returns success (no errors). However, when I pass data in POST it gives me the error shown in title. Here is my code for AJAX:

              $.ajax({
                dataType: "json",
                type: "POST",
                data: {
                        "useruid": "Nothing",
                        "type": "Office in Space",
                        "latitude": "12",
                        "longitude": "100",
                        "displayed": "true",
                        "public": "true",
                        "verified": "true",
                        "street": "Something",
                        "city": "Something",
                        "country": "Space",
                        "region": "North Space",
                        "created": "2009-03-07T00:00:00-0500",
                        "delete_status": "active"
},
                url: "/web/app_dev.php/address/",
                success: function (responseText)
                {
                    console.log("Request was successful, data received: " + JSON.stringify(responseText)); 

                },
                error: function (error) {
                    alert(JSON.stringify(error));
                }
            });

To deserialize the JSON, here is my controller code:

public function createAction(Request $request)
{


    $content = $this->get('request')->getContent();
    var_dump($content); 
    $serializer = $this->get('jms_serializer'); 
    $entity = $serializer->deserialize($content, 'Name\NameBundle\Entity\Address', 'json');
        $em = $this->getDoctrine()->getManager();
        $em->persist($entity);
        $em->flush();

    return array(
        'entity' => $entity,
        'form'   => $form->createView(),
    );

}

I am using JMSSerializer bundle. What is the reason why it cannot decode the JSON? I validated my JSON with JSONlint and it was okay. Any ideas?

** Edited code: Added Entity Class **

namespace Factory\WebServicesBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

use JMS\Serializer\Annotation\Type;

/**
 * Address
 * @ORM\Table(name="address")
 * @ORM\Entity
 */
class Address
{
/**
 * @var integer
 *
 * @ORM\Column(name="id", type="integer", nullable=false)
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="IDENTITY")
 * @JMS\Serializer\Annotation\Type("integer")
 */
private $id;

/**
 * @var string
 *
 * @ORM\Column(name="useruid", type="string", length=200, nullable=true)
 * @JMS\Serializer\Annotation\Type("string")
 */
private $useruid;

/**
 * @var string
 *
 * @ORM\Column(name="type", type="string", nullable=true)
 * @JMS\Serializer\Annotation\Type("string")
 */
private $type;

/**
 * @var string
 *
 * @ORM\Column(name="latitude", type="string", length=120, nullable=true)
 * @JMS\Serializer\Annotation\Type("string")
 */
private $latitude;

/**
 * @var string
 *
 * @ORM\Column(name="longitude", type="string", length=120, nullable=true)
 * @JMS\Serializer\Annotation\Type("string")
 */
private $longitude;

/**
 * @var boolean
 *
 * @ORM\Column(name="displayed", type="boolean", nullable=true)
 * @JMS\Serializer\Annotation\Type("boolean")
 */
private $displayed;

/**
 * @var boolean
 *
 * @ORM\Column(name="public", type="boolean", nullable=true)
 * @JMS\Serializer\Annotation\Type("boolean")
 */
private $public;

/**
 * @var boolean
 *
 * @ORM\Column(name="verified", type="boolean", nullable=true)
 * @JMS\Serializer\Annotation\Type("boolean")
 */
private $verified;

/**
 * @var string
 *
 * @ORM\Column(name="street", type="string", length=200, nullable=true)
 * @JMS\Serializer\Annotation\Type("string")
 */
private $street;

/**
 * @var string
 *
 * @ORM\Column(name="city", type="string", length=200, nullable=true)
 * @JMS\Serializer\Annotation\Type("string")
 */
private $city;

/**
 * @var string
 *
 * @ORM\Column(name="country", type="string", length=200, nullable=true)
 * @JMS\Serializer\Annotation\Type("string")
 */
private $country;

/**
 * @var string
 *
 * @ORM\Column(name="locality", type="string", length=200, nullable=true)
 * @JMS\Serializer\Annotation\Type("string")
 */
private $locality;

/**
 * @var string
 *
 * 
 * @ORM\Column(name="region", type="string", length=200, nullable=true)
 * @JMS\Serializer\Annotation\Type("string")
 */
private $region;

/**
 * @var string
 *
 * 
 * @ORM\Column(name="code", type="string", length=100, nullable=true)
 * @JMS\Serializer\Annotation\Type("string")
 * 
 */
private $code;

/**
 * 
 * @var string
 *
 * 
 * @ORM\Column(name="pobox", type="string", length=100, nullable=true)
 * @JMS\Serializer\Annotation\Type("string")
 * 
 */
private $pobox;

/**
 * @var string
 *
 * 
 * @ORM\Column(name="telephone", type="string", length=60, nullable=true)
 * @JMS\Serializer\Annotation\Type("string")
 */
private $telephone;

/**
 * @var string
 *
 * 
 * @ORM\Column(name="cellphone", type="string", length=200, nullable=true)
 * @JMS\Serializer\Annotation\Type("string")
 */
private $cellphone;

/**
 * @var string
 *
 * 
 * @ORM\Column(name="email", type="string", length=200, nullable=true)
 * @JMS\Serializer\Annotation\Type("string")
 */
private $email;

/**
 * @var string
 *
 * 
 * @ORM\Column(name="facsmile", type="string", length=60, nullable=true)
 * @JMS\Serializer\Annotation\Type("string")
 */
private $facsmile;

/**
 * @var \DateTime
 *
 * 
 * @ORM\Column(name="created", type="datetime", nullable=true)
 * @JMS\Serializer\Annotation\Type("DateTime")
 */
private $created;

/**
 * @var \DateTime
 *
 * 
 * @ORM\Column(name="modified", type="datetime", nullable=true)
 * @JMS\Serializer\Annotation\Type("DateTime")
 */
private $modified;

/**
 * @var string
 *
 * 
 * @ORM\Column(name="delete_status", type="string", nullable=true)
 * @JMS\Serializer\Annotation\Type("string")
 */
private $deleteStatus;
Was it helpful?

Solution

You have to instruct the JMS Serializer in how to deserialize your fields.
You can do that by using annotations, e.g. @JMS\Serializer\Annotation\Type("string")
The JMS Serializer documentation lists all possible types.

Just to be clear, you put the annotation on every field of your entity that you want to be deserialized, e.g.

/**
 * @var string
 *
 * @JMS\Serializer\Annotation\Type("string")
 * @ORM\Column(name="street", type="string", length=200, nullable=true)
 */
private $street;

Hope this helps...

OTHER TIPS

The problem (at least the current problem) is that JSON is not being posted. As such the request body is indeed not JSON: userId=..&type=.. etc.

This is because the data of $.ajax is not serialized to JSON. Instead the object is being mapped to query key/value pairs:

By default, data passed in to the data option as an object (technically, anything other than a string) will be processed and transformed into a query string, fitting to the default content-type "application/x-www-form-urlencoded" ..

The easiest fix is to actually send JSON:

$.ajax({
    dataType: "json",               // this is only for the response!
    type: "POST",
    data: JSON.stringify(theData),  // since (JSON) string, won't be processed
    // ..
})

Remember that JSON is text and JavaScript objects are not JSON!

Use json3.js or equivalent shim to support older/archaic browsers.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top