Reputation: 597
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;
Upvotes: 0
Views: 13920
Reputation: 61865
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.
Upvotes: 2
Reputation: 457
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...
Upvotes: 2