diff --git a/core/modules/hal/src/Normalizer/FieldItemNormalizer.php b/core/modules/hal/src/Normalizer/FieldItemNormalizer.php
index 376a444..5ad472a 100644
--- a/core/modules/hal/src/Normalizer/FieldItemNormalizer.php
+++ b/core/modules/hal/src/Normalizer/FieldItemNormalizer.php
@@ -21,7 +21,11 @@ class FieldItemNormalizer extends NormalizerBase {
    * {@inheritdoc}
    */
   public function normalize($field_item, $format = NULL, array $context = array()) {
-    $values = $field_item->toArray();
+    $values = [];
+    foreach ($field_item as $property => $data_item) {
+      $values[$property] = $this->serializer->normalize($data_item, $format, $context);
+    }
+
     if (isset($context['langcode'])) {
       $values['lang'] = $context['langcode'];
     }
diff --git a/core/modules/hal/tests/src/Kernel/FileNormalizeTest.php b/core/modules/hal/tests/src/Kernel/FileNormalizeTest.php
index 42d7a36..199c39e 100644
--- a/core/modules/hal/tests/src/Kernel/FileNormalizeTest.php
+++ b/core/modules/hal/tests/src/Kernel/FileNormalizeTest.php
@@ -33,20 +33,6 @@ class FileNormalizeTest extends NormalizerTestBase {
   protected function setUp() {
     parent::setUp();
     $this->installEntitySchema('file');
-
-    $entity_manager = \Drupal::entityManager();
-    $link_manager = new LinkManager(new TypeLinkManager(new MemoryBackend(), \Drupal::moduleHandler(), \Drupal::service('config.factory'), \Drupal::service('request_stack'), \Drupal::service('entity_type.bundle.info')), new RelationLinkManager(new MemoryBackend(), $entity_manager, \Drupal::moduleHandler(), \Drupal::service('config.factory'), \Drupal::service('request_stack')));
-
-    // Set up the mock serializer.
-    $normalizers = array(
-      new FieldItemNormalizer(),
-      new FileEntityNormalizer($entity_manager, \Drupal::httpClient(), $link_manager, \Drupal::moduleHandler()),
-    );
-
-    $encoders = array(
-      new JsonEncoder(),
-    );
-    $this->serializer = new Serializer($normalizers, $encoders);
   }
 
 
diff --git a/core/modules/hal/tests/src/Kernel/NormalizerTestBase.php b/core/modules/hal/tests/src/Kernel/NormalizerTestBase.php
index 5867476..34745e3 100644
--- a/core/modules/hal/tests/src/Kernel/NormalizerTestBase.php
+++ b/core/modules/hal/tests/src/Kernel/NormalizerTestBase.php
@@ -130,23 +130,7 @@ protected function setUp() {
       'translatable' => TRUE,
     ])->save();
 
-    $entity_manager = \Drupal::entityManager();
-    $link_manager = new LinkManager(new TypeLinkManager(new MemoryBackend(), \Drupal::moduleHandler(), \Drupal::service('config.factory'), \Drupal::service('request_stack'), \Drupal::service('entity_type.bundle.info')), new RelationLinkManager(new MemoryBackend(), $entity_manager, \Drupal::moduleHandler(), \Drupal::service('config.factory'), \Drupal::service('request_stack')));
-
-    $chain_resolver = new ChainEntityResolver(array(new UuidResolver($entity_manager), new TargetIdResolver()));
-
-    // Set up the mock serializer.
-    $normalizers = array(
-      new ContentEntityNormalizer($link_manager, $entity_manager, \Drupal::moduleHandler()),
-      new EntityReferenceItemNormalizer($link_manager, $chain_resolver),
-      new FieldItemNormalizer(),
-      new FieldNormalizer(),
-    );
-
-    $encoders = array(
-      new JsonEncoder(),
-    );
-    $this->serializer = new Serializer($normalizers, $encoders);
+    $this->serializer = $this->container->get('serializer');
   }
 
 }
diff --git a/core/modules/serialization/serialization.services.yml b/core/modules/serialization/serialization.services.yml
index 8b570c0..6bfabdb 100644
--- a/core/modules/serialization/serialization.services.yml
+++ b/core/modules/serialization/serialization.services.yml
@@ -17,6 +17,10 @@ services:
     tags:
       - { name: normalizer }
     arguments: ['@entity.manager']
+  serializer.normalizer.primitive_data:
+    class: Drupal\serialization\Normalizer\PrimitiveDataNormalizer
+    tags:
+      - { name: normalizer, priority: 5 }
   serializer.normalizer.complex_data:
     class: Drupal\serialization\Normalizer\ComplexDataNormalizer
     tags:
diff --git a/core/modules/serialization/src/Normalizer/PrimitiveDataNormalizer.php b/core/modules/serialization/src/Normalizer/PrimitiveDataNormalizer.php
new file mode 100644
index 0000000..4ebf7a4
--- /dev/null
+++ b/core/modules/serialization/src/Normalizer/PrimitiveDataNormalizer.php
@@ -0,0 +1,26 @@
+<?php
+
+namespace Drupal\serialization\Normalizer;
+
+use Drupal\Core\TypedData\PrimitiveInterface;
+
+/**
+ * Converts primitive data objects to their casted values.
+ */
+class PrimitiveDataNormalizer extends NormalizerBase {
+
+  /**
+   * The interface or class that this Normalizer supports.
+   *
+   * @var string
+   */
+  protected $supportedInterfaceOrClass = PrimitiveInterface::class;
+
+  /**
+   * {@inheritdoc}
+   */
+  public function normalize($object, $format = NULL, array $context = array()) {
+    return $object->getCastedValue();
+  }
+
+}
diff --git a/core/modules/serialization/tests/src/Kernel/EntitySerializationTest.php b/core/modules/serialization/tests/src/Kernel/EntitySerializationTest.php
index 0f84d3d..18c652e 100644
--- a/core/modules/serialization/tests/src/Kernel/EntitySerializationTest.php
+++ b/core/modules/serialization/tests/src/Kernel/EntitySerializationTest.php
@@ -110,7 +110,8 @@ public function testNormalize() {
       ),
       'user_id' => array(
         array(
-          'target_id' => $this->user->id(),
+          // id() will return the string value as it comes from the database.
+          'target_id' => (int) $this->user->id(),
           'target_type' => $this->user->getEntityTypeId(),
           'target_uuid' => $this->user->uuid(),
           'url' => $this->user->url(),
@@ -134,7 +135,7 @@ public function testNormalize() {
     $normalized = $this->serializer->normalize($this->entity);
 
     foreach (array_keys($expected) as $fieldName) {
-      $this->assertEqual($expected[$fieldName], $normalized[$fieldName], "ComplexDataNormalizer produces expected array for $fieldName.");
+      $this->assertSame($expected[$fieldName], $normalized[$fieldName], "Normalization produces expected array for $fieldName.");
     }
     $this->assertEqual(array_diff_key($normalized, $expected), array(), 'No unexpected data is added to the normalized array.');
   }
diff --git a/core/modules/serialization/tests/src/Unit/Normalizer/PrimitiveDataNormalizerTest.php b/core/modules/serialization/tests/src/Unit/Normalizer/PrimitiveDataNormalizerTest.php
new file mode 100644
index 0000000..63e5555
--- /dev/null
+++ b/core/modules/serialization/tests/src/Unit/Normalizer/PrimitiveDataNormalizerTest.php
@@ -0,0 +1,80 @@
+<?php
+
+namespace Drupal\Tests\serialization\Unit\Normalizer;
+
+use Drupal\Core\TypedData\DataDefinition;
+use Drupal\Core\TypedData\Plugin\DataType\BooleanData;
+use Drupal\Core\TypedData\Plugin\DataType\IntegerData;
+use Drupal\Core\TypedData\Plugin\DataType\StringData;
+use Drupal\Tests\UnitTestCase;
+use Drupal\serialization\Normalizer\PrimitiveDataNormalizer;
+
+/**
+ * @coversDefaultClass \Drupal\serialization\Normalizer\TypedDataNormalizer
+ * @group serialization
+ */
+class PrimitiveDataNormalizerTest extends UnitTestCase {
+
+  /**
+   * The TypedDataNormalizer instance.
+   *
+   * @var \Drupal\serialization\Normalizer\TypedDataNormalizer
+   */
+  protected $normalizer;
+
+  protected function setUp() {
+    $this->normalizer = new PrimitiveDataNormalizer();
+  }
+
+  /**
+   * @covers ::supportsNormalization
+   * @dataProvider dataProviderPrimitiveData
+   */
+  public function testSupportsNormalization($primitive_data, $value) {
+    $this->assertTrue($this->normalizer->supportsNormalization($primitive_data));
+  }
+
+  /**
+   * @covers ::supportsNormalization
+   */
+  public function testSupportsNormalizationFail() {
+    // Test that an object not implementing TypedDataInterface fails.
+    $this->assertFalse($this->normalizer->supportsNormalization(new \stdClass()));
+  }
+
+  /**
+   * @covers ::normalize
+   * @dataProvider dataProviderPrimitiveData
+   */
+  public function testNormalize($primitive_data, $value) {
+    $this->assertSame($value, $this->normalizer->normalize($primitive_data));
+  }
+
+  /**
+   * Data provider for testNormalize().
+   */
+  public function dataProviderPrimitiveData() {
+    $data = [];
+
+    $definition = DataDefinition::createFromDataType('string');
+    $string = new StringData($definition, 'string');
+    $string->setValue('test');
+
+    $data['string'] = [$string, 'test'];
+
+    $definition = DataDefinition::createFromDataType('integer');
+    $integer = new IntegerData($definition, 'integer');
+    $integer->setValue(5);
+
+    $data['integer'] = [$integer, 5];
+
+    $definition = DataDefinition::createFromDataType('boolean');
+    $boolean = new BooleanData($definition, 'boolean');
+    $boolean->setValue(TRUE);
+
+    $data['boolean'] = [$boolean, TRUE];
+
+    return $data;
+  }
+
+}
