diff --git a/core/core.services.yml b/core/core.services.yml
index 60fd6d5..6094635 100644
--- a/core/core.services.yml
+++ b/core/core.services.yml
@@ -855,6 +855,10 @@ services:
     arguments: ['@class_resolver', '@current_route_match', '%main_content_renderers%']
     tags:
       - { name: event_subscriber }
+  accept_negotiation_406:
+    class: Drupal\Core\EventSubscriber\AcceptNegotiation406
+    tags:
+      - { name: event_subscriber, priority: -10 }
   main_content_renderer.html:
     class: Drupal\Core\Render\MainContent\HtmlRenderer
     arguments: ['@title_resolver', '@plugin.manager.display_variant', '@event_dispatcher', '@element_info', '@module_handler', '@renderer', '@render_cache', '@cache_contexts_manager']
@@ -887,11 +891,6 @@ services:
     tags:
       - { name: event_subscriber }
     arguments: ['@router', '@router.request_context', NULL, '@request_stack']
-  view_subscriber:
-    class: Drupal\Core\EventSubscriber\ViewSubscriber
-    arguments: ['@title_resolver']
-    tags:
-      - { name: event_subscriber }
   bare_html_page_renderer:
     class: Drupal\Core\Render\BareHtmlPageRenderer
     arguments: ['@renderer']
diff --git a/core/lib/Drupal/Core/ContentNegotiation.php b/core/lib/Drupal/Core/ContentNegotiation.php
index 857f9d5..3322af8 100644
--- a/core/lib/Drupal/Core/ContentNegotiation.php
+++ b/core/lib/Drupal/Core/ContentNegotiation.php
@@ -38,7 +38,7 @@ public function getContentType(Request $request) {
 
     // Check all formats, if priority format is found return it.
     $first_found_format = FALSE;
-    $priority = array('html', 'drupal_ajax', 'drupal_modal', 'drupal_dialog');
+    $priority = array('html');
     foreach ($request->getAcceptableContentTypes() as $mime_type) {
       $format = $request->getFormat($mime_type);
       if (in_array($format, $priority, TRUE)) {
diff --git a/core/lib/Drupal/Core/EventSubscriber/AcceptNegotiation406.php b/core/lib/Drupal/Core/EventSubscriber/AcceptNegotiation406.php
new file mode 100644
index 0000000..da4fa32
--- /dev/null
+++ b/core/lib/Drupal/Core/EventSubscriber/AcceptNegotiation406.php
@@ -0,0 +1,44 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\EventSubscriber\AcceptNegotiation406.
+ */
+
+namespace Drupal\Core\EventSubscriber;
+
+use Symfony\Component\EventDispatcher\EventSubscriberInterface;
+use Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent;
+use Symfony\Component\HttpKernel\Exception\NotAcceptableHttpException;
+use Symfony\Component\HttpKernel\KernelEvents;
+
+/**
+ * View subscriber rendering a 406 if we could not route or render a request.
+ *
+ * @todo fix or replace this in https://www.drupal.org/node/2364011
+ */
+class AcceptNegotiation406 implements EventSubscriberInterface {
+
+  function onViewDetect406(GetResponseForControllerResultEvent $event) {
+    $request = $event->getRequest();
+    $result = $event->getControllerResult();
+
+    // If this is a render array then we assume that the router went with the
+    // generic controller and not one with a format. If the format requested is
+    // not HTML though we can also assume that the requested format is invalid
+    // so we provide a 406 response.
+    if (is_array($result) && $request->getRequestFormat() !== 'html') {
+      throw new NotAcceptableHttpException('Not acceptable');
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  static function getSubscribedEvents() {
+    $events[KernelEvents::VIEW][] = ['onViewDetect406', -10];
+
+    return $events;
+  }
+
+}
diff --git a/core/lib/Drupal/Core/EventSubscriber/ExceptionJsonSubscriber.php b/core/lib/Drupal/Core/EventSubscriber/ExceptionJsonSubscriber.php
index 9610e8d..70e4208 100644
--- a/core/lib/Drupal/Core/EventSubscriber/ExceptionJsonSubscriber.php
+++ b/core/lib/Drupal/Core/EventSubscriber/ExceptionJsonSubscriber.php
@@ -65,4 +65,15 @@ public function on405(GetResponseForExceptionEvent $event) {
     $event->setResponse($response);
   }
 
+  /**
+   * Handles a 406 error for JSON.
+   *
+   * @param \Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent $event
+   *   The event to process.
+   */
+  public function on406(GetResponseForExceptionEvent $event) {
+    $response = new JsonResponse(array('message' => $event->getException()->getMessage()), Response::HTTP_NOT_ACCEPTABLE);
+    $event->setResponse($response);
+  }
+
 }
diff --git a/core/lib/Drupal/Core/EventSubscriber/MainContentViewSubscriber.php b/core/lib/Drupal/Core/EventSubscriber/MainContentViewSubscriber.php
index fcc51a3..f98fb71 100644
--- a/core/lib/Drupal/Core/EventSubscriber/MainContentViewSubscriber.php
+++ b/core/lib/Drupal/Core/EventSubscriber/MainContentViewSubscriber.php
@@ -10,8 +10,6 @@
 use Drupal\Core\DependencyInjection\ClassResolverInterface;
 use Drupal\Core\Routing\RouteMatchInterface;
 use Symfony\Component\EventDispatcher\EventSubscriberInterface;
-use Symfony\Component\HttpFoundation\JsonResponse;
-use Symfony\Component\HttpFoundation\Response;
 use Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent;
 use Symfony\Component\HttpKernel\KernelEvents;
 
@@ -51,6 +49,13 @@ class MainContentViewSubscriber implements EventSubscriberInterface {
   protected $mainContentRenderers;
 
   /**
+   * URL query attribute to indicate the wrapper used to render a request.
+   *
+   * This controls wrapping the HTML content for example in a modal dialog.
+   */
+  const WRAPPER_ENVELOPE = '_wrapper_format';
+
+  /**
    * Constructs a new MainContentViewSubscriber object.
    *
    * @param \Drupal\Core\DependencyInjection\ClassResolverInterface $class_resolver
@@ -76,22 +81,15 @@ public function onViewRenderArray(GetResponseForControllerResultEvent $event) {
     $request = $event->getRequest();
     $result = $event->getControllerResult();
 
-    $format = $request->getRequestFormat();
-
     // Render the controller result into a response if it's a render array.
-    if (is_array($result)) {
-      if (isset($this->mainContentRenderers[$format])) {
-        $renderer = $this->classResolver->getInstanceFromDefinition($this->mainContentRenderers[$format]);
-        $event->setResponse($renderer->renderResponse($result, $request, $this->routeMatch));
-      }
-      else {
-        $supported_formats = array_keys($this->mainContentRenderers);
-        $supported_mimetypes = array_map([$request, 'getMimeType'], $supported_formats);
-        $event->setResponse(new JsonResponse([
-          'message' => 'Not Acceptable.',
-          'supported_mime_types' => $supported_mimetypes,
-        ], 406));
-      }
+    if (is_array($result) && ($request->query->has(static::WRAPPER_ENVELOPE) || $request->getRequestFormat() == 'html')) {
+      $wrapper = $request->query->get(static::WRAPPER_ENVELOPE, 'html');
+
+      // Fall back to HTML if the requested wrapper envelope is not available.
+      $wrapper = isset($this->mainContentRenderers[$wrapper]) ? $wrapper : 'html';
+
+      $renderer = $this->classResolver->getInstanceFromDefinition($this->mainContentRenderers[$wrapper]);
+      $event->setResponse($renderer->renderResponse($result, $request, $this->routeMatch));
     }
   }
 
diff --git a/core/lib/Drupal/Core/EventSubscriber/ViewSubscriber.php b/core/lib/Drupal/Core/EventSubscriber/ViewSubscriber.php
deleted file mode 100644
index 3485f19..0000000
--- a/core/lib/Drupal/Core/EventSubscriber/ViewSubscriber.php
+++ /dev/null
@@ -1,92 +0,0 @@
-<?php
-
-/**
- * @file
- * Definition of Drupal\Core\EventSubscriber\ViewSubscriber.
- */
-
-namespace Drupal\Core\EventSubscriber;
-
-use Drupal\Core\Controller\TitleResolverInterface;
-use Symfony\Cmf\Component\Routing\RouteObjectInterface;
-use Symfony\Component\HttpFoundation\Response;
-use Symfony\Component\HttpFoundation\JsonResponse;
-use Symfony\Component\HttpKernel\KernelEvents;
-use Symfony\Component\HttpKernel\HttpKernelInterface;
-use Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent;
-use Symfony\Component\EventDispatcher\EventSubscriberInterface;
-
-/**
- * Main subscriber for VIEW HTTP responses.
- *
- * @todo This needs to get refactored to be extensible so that we can handle
- *   more than just Html and Drupal-specific JSON requests. See
- *   http://drupal.org/node/1594870
- */
-class ViewSubscriber implements EventSubscriberInterface {
-
-  /**
-   * The title resolver.
-   *
-   * @var \Drupal\Core\Controller\TitleResolverInterface
-   */
-  protected $titleResolver;
-
-  /**
-   * Constructs a new ViewSubscriber.
-   *
-   * @param \Drupal\Core\Controller\TitleResolverInterface $title_resolver
-   *   The title resolver.
-   */
-  public function __construct(TitleResolverInterface $title_resolver) {
-    $this->titleResolver = $title_resolver;
-  }
-
-  /**
-   * Processes a successful controller into an HTTP 200 response.
-   *
-   * Some controllers may not return a response object but simply the body of
-   * one.  The VIEW event is called in that case, to allow us to mutate that
-   * body into a Response object.  In particular we assume that the return
-   * from an JSON-type response is a JSON string, so just wrap it into a
-   * Response object.
-   *
-   * @param \Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent $event
-   *   The Event to process.
-   */
-  public function onView(GetResponseForControllerResultEvent $event) {
-    $request = $event->getRequest();
-
-    if ($event->getRequestType() == HttpKernelInterface::MASTER_REQUEST) {
-      $method = 'on' . $request->getRequestFormat();
-
-      if (method_exists($this, $method)) {
-        $event->setResponse($this->$method($event));
-      }
-      else {
-        $event->setResponse(new Response('Not Acceptable', 406));
-      }
-    }
-  }
-
-  public function onJson(GetResponseForControllerResultEvent $event) {
-    $page_callback_result = $event->getControllerResult();
-
-    $response = new JsonResponse();
-    $response->setData($page_callback_result);
-
-    return $response;
-  }
-
-  /**
-   * Registers the methods in this class that should be listeners.
-   *
-   * @return array
-   *   An array of event listener definitions.
-   */
-  static function getSubscribedEvents() {
-    $events[KernelEvents::VIEW][] = array('onView');
-
-    return $events;
-  }
-}
diff --git a/core/lib/Drupal/Core/Render/Element/RenderElement.php b/core/lib/Drupal/Core/Render/Element/RenderElement.php
index 0283333..b9de164 100644
--- a/core/lib/Drupal/Core/Render/Element/RenderElement.php
+++ b/core/lib/Drupal/Core/Render/Element/RenderElement.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\Core\Render\Element;
 
+use Drupal\Core\EventSubscriber\MainContentViewSubscriber;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Plugin\PluginBase;
 use Drupal\Core\Render\Element;
@@ -240,7 +241,7 @@ public static function preRenderAjaxForm($element) {
       $settings += array(
         'url' => isset($settings['callback']) ? Url::fromRoute('system.ajax') : NULL,
         'options' => array(),
-        'accepts' => 'application/vnd.drupal-ajax'
+        MainContentViewSubscriber::WRAPPER_ENVELOPE => 'ajax',
       );
 
       // @todo Legacy support. Remove in Drupal 8.
diff --git a/core/misc/ajax.js b/core/misc/ajax.js
index e2aeab1..b6864e7 100644
--- a/core/misc/ajax.js
+++ b/core/misc/ajax.js
@@ -52,7 +52,7 @@
           element_settings.url = $(this).attr('href');
           element_settings.event = 'click';
         }
-        element_settings.accepts = $(this).data('accepts');
+        element_settings.dialogType = $(this).data('dialog-type');
         element_settings.dialog = $(this).data('dialog-options');
         var baseUseAjax = $(this).attr('id');
         Drupal.ajax[baseUseAjax] = new Drupal.ajax(baseUseAjax, this, element_settings);
@@ -256,9 +256,6 @@
         }
       },
       dataType: 'json',
-      accepts: {
-        json: element_settings.accepts || 'application/vnd.drupal-ajax'
-      },
       type: 'POST'
     };
 
@@ -266,6 +263,16 @@
       ajax.options.data.dialogOptions = element_settings.dialog;
     }
 
+    // Ensure that we have a valid URL by adding ? when no query parameter is
+    // yet available, otherwise append using &.
+    if (ajax.options.url.indexOf('?') === -1) {
+      ajax.options.url += '?';
+    }
+    else {
+      ajax.options.url += '&';
+    }
+    ajax.options.url += Drupal.ajax.WRAPPER_ENVELOPE + '=drupal_' + (element_settings.dialogType || 'ajax');
+
     // Bind the ajaxSubmit function to the element event.
     $(ajax.element).on(element_settings.event, function (event) {
       return ajax.eventResponse(this, event);
@@ -289,6 +296,13 @@
   };
 
   /**
+   * Url query attribute to indicate the wrapper used to render a request.
+   *
+   * This controls wrapping the HTML content for example in a modal dialog.
+   */
+  Drupal.ajax.WRAPPER_ENVELOPE = '_wrapper_format';
+
+  /**
    * Handle a key press.
    *
    * The Ajax object will, if instructed, bind to a key press response. This
diff --git a/core/modules/block/src/BlockListBuilder.php b/core/modules/block/src/BlockListBuilder.php
index 6521287..913b718 100644
--- a/core/modules/block/src/BlockListBuilder.php
+++ b/core/modules/block/src/BlockListBuilder.php
@@ -362,7 +362,7 @@ public function buildForm(array $form, FormStateInterface $form_state) {
         ]),
         'attributes' => array(
           'class' => array('use-ajax', 'block-filter-text-source'),
-          'data-accepts' => 'application/vnd.drupal-modal',
+          'data-dialog-type' => 'modal',
           'data-dialog-options' => Json::encode(array(
             'width' => 700,
           )),
diff --git a/core/modules/ckeditor/js/ckeditor.js b/core/modules/ckeditor/js/ckeditor.js
index 1596808..3df3366 100644
--- a/core/modules/ckeditor/js/ckeditor.js
+++ b/core/modules/ckeditor/js/ckeditor.js
@@ -160,9 +160,10 @@
       // a Drupal.ajax instance to load the dialog and trigger it.
       var $content = $('<div class="ckeditor-dialog-loading"><span style="top: -40px;" class="ckeditor-dialog-loading-link"><a>' + Drupal.t('Loading...') + '</a></span></div>');
       $content.appendTo($target);
+
       new Drupal.ajax('ckeditor-dialog', $content.find('a').get(0), {
-        accepts: 'application/vnd.drupal-modal',
         dialog: dialogSettings,
+        dialogType: 'modal',
         selector: '.ckeditor-dialog-loading-link',
         url: url,
         event: 'ckeditor-internal.ckeditor',
diff --git a/core/modules/config/src/Form/ConfigSync.php b/core/modules/config/src/Form/ConfigSync.php
index b97218b..0a91758 100644
--- a/core/modules/config/src/Form/ConfigSync.php
+++ b/core/modules/config/src/Form/ConfigSync.php
@@ -281,7 +281,7 @@ public function buildForm(array $form, FormStateInterface $form_state) {
             'url' => Url::fromRoute($route_name, $route_options),
             'attributes' => array(
               'class' => array('use-ajax'),
-              'data-accepts' => 'application/vnd.drupal-modal',
+              'data-dialog-type' => 'modal',
               'data-dialog-options' => json_encode(array(
                 'width' => 700
               )),
diff --git a/core/modules/rest/src/Routing/ResourceRoutes.php b/core/modules/rest/src/Routing/ResourceRoutes.php
index 9cc60b1..484c48e 100644
--- a/core/modules/rest/src/Routing/ResourceRoutes.php
+++ b/core/modules/rest/src/Routing/ResourceRoutes.php
@@ -19,7 +19,7 @@
 /**
  * Subscriber for REST-style routes.
  */
-class ResourceRoutes extends RouteSubscriberBase{
+class ResourceRoutes extends RouteSubscriberBase {
 
   /**
    * The plugin manager for REST plugins.
diff --git a/core/modules/rest/src/Tests/ReadTest.php b/core/modules/rest/src/Tests/ReadTest.php
index d5f2fc1..6d8ff11 100644
--- a/core/modules/rest/src/Tests/ReadTest.php
+++ b/core/modules/rest/src/Tests/ReadTest.php
@@ -92,7 +92,9 @@ public function testRead() {
     // and hence when there is no matching REST route, the non-REST route is
     // used, but it can't render into application/hal+json, so it returns a 406.
     $this->assertResponse('406', 'HTTP response code is 406 when the resource does not define formats, because it falls back to the canonical, non-REST route.');
-    $this->assertTrue(strpos($response, '{"message":"Not Acceptable.","supported_mime_types":') !== FALSE);
+    $this->assertEqual($response, Json::encode([
+      'message' => 'Not Acceptable.',
+    ]));
   }
 
   /**
diff --git a/core/modules/rest/src/Tests/ResourceTest.php b/core/modules/rest/src/Tests/ResourceTest.php
index be02617..5144ae3 100644
--- a/core/modules/rest/src/Tests/ResourceTest.php
+++ b/core/modules/rest/src/Tests/ResourceTest.php
@@ -54,7 +54,7 @@ public function testFormats() {
     $this->config->save();
     $this->rebuildCache();
 
-    // Verify that accessing the resource returns 401.
+    // Verify that accessing the resource returns 406.
     $response = $this->httpRequest($this->entity->urlInfo(), 'GET', NULL, $this->defaultMimeType);
     // AcceptHeaderMatcher considers the canonical, non-REST route a match, but
     // a lower quality one: no format restrictions means there's always a match,
diff --git a/core/modules/simpletest/src/WebTestBase.php b/core/modules/simpletest/src/WebTestBase.php
index fe96f9f..a8e99d6 100644
--- a/core/modules/simpletest/src/WebTestBase.php
+++ b/core/modules/simpletest/src/WebTestBase.php
@@ -13,6 +13,7 @@
 use Drupal\Component\Utility\Crypt;
 use Drupal\Component\Utility\Html;
 use Drupal\Component\Utility\NestedArray;
+use Drupal\Component\Utility\UrlHelper;
 use Drupal\Core\Cache\Cache;
 use Drupal\Component\Utility\SafeMarkup;
 use Drupal\Core\DependencyInjection\YamlFileLoader;
@@ -20,6 +21,7 @@
 use Drupal\Core\Database\Database;
 use Drupal\Core\Database\ConnectionNotDefinedException;
 use Drupal\Core\Entity\EntityInterface;
+use Drupal\Core\EventSubscriber\MainContentViewSubscriber;
 use Drupal\Core\Language\LanguageInterface;
 use Drupal\Core\Render\Element;
 use Drupal\Core\Session\AccountInterface;
@@ -1556,8 +1558,8 @@ protected function drupalGetJSON($path, array $options = array(), array $headers
    * Requests a Drupal path in drupal_ajax format and JSON-decodes the response.
    */
   protected function drupalGetAjax($path, array $options = array(), array $headers = array()) {
-    if (!preg_grep('/^Accept:/', $headers)) {
-      $headers[] = 'Accept: application/vnd.drupal-ajax';
+    if (!isset($options['query'][MainContentViewSubscriber::WRAPPER_ENVELOPE])) {
+      $options['query'][MainContentViewSubscriber::WRAPPER_ENVELOPE] = 'drupal_ajax';
     }
     return Json::decode($this->drupalGet($path, $options, $headers));
   }
@@ -1785,6 +1787,11 @@ protected function drupalPostForm($path, $edit, $submit, array $options = array(
    * @see ajax.js
    */
   protected function drupalPostAjaxForm($path, $edit, $triggering_element, $ajax_path = NULL, array $options = array(), array $headers = array(), $form_html_id = NULL, $ajax_settings = NULL) {
+    if (isset($options['query'][MainContentViewSubscriber::WRAPPER_ENVELOPE])) {
+      $original_wrapper = $options['query'][MainContentViewSubscriber::WRAPPER_ENVELOPE];
+      unset($options['query'][MainContentViewSubscriber::WRAPPER_ENVELOPE]);
+    }
+
     // Get the content of the initial page prior to calling drupalPostForm(),
     // since drupalPostForm() replaces $this->content.
     if (isset($path)) {
@@ -1793,8 +1800,11 @@ protected function drupalPostAjaxForm($path, $edit, $triggering_element, $ajax_p
     $content = $this->content;
     $drupal_settings = $this->drupalSettings;
 
-    if (!preg_grep('/^Accept:/', $headers)) {
-      $headers[] = 'Accept: application/vnd.drupal-ajax';
+    if (isset($original_wrapper)) {
+      $options['query'][MainContentViewSubscriber::WRAPPER_ENVELOPE] = $original_wrapper;
+    }
+    else {
+      $options['query'][MainContentViewSubscriber::WRAPPER_ENVELOPE] = 'drupal_ajax';
     }
 
     // Get the Ajax settings bound to the triggering element.
@@ -1834,8 +1844,21 @@ protected function drupalPostAjaxForm($path, $edit, $triggering_element, $ajax_p
     // Unless a particular path is specified, use the one specified by the
     // Ajax settings, or else 'system/ajax'.
     if (!isset($ajax_path)) {
-      $ajax_path = isset($ajax_settings['url']) ? $ajax_settings['url'] : 'system/ajax';
+      if (isset($ajax_settings['url'])) {
+        $parsed_url = UrlHelper::parse($ajax_settings['url']);
+        $options['query'] = $parsed_url['query'] + $options['query'];
+        $options += ['fragment' => $parsed_url['fragment']];
+        $ajax_path = preg_replace(
+          '/^' . preg_quote($GLOBALS['base_path'], '/') . '/',
+          '',
+          $parsed_url['path']
+        );
+      }
+      else {
+        $ajax_path = 'system/ajax';
+      }
     }
+    $ajax_path = $this->container->get('unrouted_url_assembler')->assemble('base://' . $ajax_path, $options);
 
     // Submit the POST request.
     $return = Json::decode($this->drupalPostForm(NULL, $edit, array('path' => $ajax_path, 'triggering_element' => $triggering_element), $options, $headers, $form_html_id, $extra_post));
diff --git a/core/modules/system/src/Tests/Ajax/DialogTest.php b/core/modules/system/src/Tests/Ajax/DialogTest.php
index 482e025..c78e94c 100644
--- a/core/modules/system/src/Tests/Ajax/DialogTest.php
+++ b/core/modules/system/src/Tests/Ajax/DialogTest.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\system\Tests\Ajax;
 
+use Drupal\Core\EventSubscriber\MainContentViewSubscriber;
 use Drupal\Core\Url;
 
 /**
@@ -93,7 +94,7 @@ public function testDialog() {
     $this->assertRaw($dialog_contents, 'Non-JS modal dialog page present.');
 
     // Emulate going to the JS version of the page and check the JSON response.
-    $ajax_result = $this->drupalGetAjax('ajax-test/dialog-contents', array(), array('Accept: application/vnd.drupal-modal'));
+    $ajax_result = $this->drupalGetAjax('ajax-test/dialog-contents', array('query' => array(MainContentViewSubscriber::WRAPPER_ENVELOPE => 'drupal_modal')));
     $this->assertEqual($modal_expected_response, $ajax_result[3], 'Modal dialog JSON response matches.');
 
     // Check that requesting a "normal" dialog without JS goes to a page.
@@ -106,7 +107,7 @@ public function testDialog() {
     $ajax_result = $this->drupalPostAjaxForm('ajax-test/dialog', array(
         // We have to mock a form element to make drupalPost submit from a link.
         'textfield' => 'test',
-      ), array(), 'ajax-test/dialog-contents', array(), array('Accept: application/vnd.drupal-dialog'), NULL, array(
+      ), array(), 'ajax-test/dialog-contents', array('query' => array(MainContentViewSubscriber::WRAPPER_ENVELOPE => 'drupal_dialog')), array(), NULL, array(
       'submit' => array(
         'dialogOptions[target]' => 'ajax-test-dialog-wrapper-1',
       )
@@ -119,7 +120,7 @@ public function testDialog() {
     $ajax_result = $this->drupalPostAjaxForm('ajax-test/dialog', array(
         // We have to mock a form element to make drupalPost submit from a link.
         'textfield' => 'test',
-      ), array(), 'ajax-test/dialog-contents', array(), array('Accept: application/vnd.drupal-dialog'), NULL, array(
+      ), array(), 'ajax-test/dialog-contents', array('query' => array(MainContentViewSubscriber::WRAPPER_ENVELOPE => 'drupal_dialog')), array(), NULL, array(
       // Don't send a target.
       'submit' => array()
     ));
@@ -159,13 +160,13 @@ public function testDialog() {
     $this->assertTrue(!empty($form), 'Non-JS form page present.');
 
     // Emulate going to the JS version of the form and check the JSON response.
-    $ajax_result = $this->drupalGetAjax('ajax-test/dialog-form', array(), array('Accept: application/vnd.drupal-modal'));
+    $ajax_result = $this->drupalGetAjax('ajax-test/dialog-form', array('query' => array(MainContentViewSubscriber::WRAPPER_ENVELOPE => 'drupal_modal')));
     $expected_ajax_settings = [
       'edit-preview' => [
         'callback' => '::preview',
         'event' => 'click',
         'url' => Url::fromRoute('system.ajax')->toString(),
-        'accepts' => 'application/vnd.drupal-ajax',
+        MainContentViewSubscriber::WRAPPER_ENVELOPE => 'ajax',
         'submit' => [
           '_triggering_element_name' => 'op',
           '_triggering_element_value' => 'Preview',
@@ -188,7 +189,7 @@ public function testDialog() {
     $this->assertTrue(!empty($form), 'Non-JS entity form page present.');
 
     // Emulate going to the JS version of the form and check the JSON response.
-    $ajax_result = $this->drupalGetAjax('admin/structure/contact/add', array(), array('Accept: application/vnd.drupal-modal'));
+    $ajax_result = $this->drupalGetAjax('admin/structure/contact/add', array('query' => array(MainContentViewSubscriber::WRAPPER_ENVELOPE => 'drupal_modal')));
     $this->setRawContent($ajax_result[3]['data']);
     // Remove the data, the form build id and token will never match.
     unset($ajax_result[3]['data']);
diff --git a/core/modules/system/tests/modules/ajax_test/src/Controller/AjaxTestController.php b/core/modules/system/tests/modules/ajax_test/src/Controller/AjaxTestController.php
index b54b823..3c49597 100644
--- a/core/modules/system/tests/modules/ajax_test/src/Controller/AjaxTestController.php
+++ b/core/modules/system/tests/modules/ajax_test/src/Controller/AjaxTestController.php
@@ -11,6 +11,7 @@
 use Drupal\Core\Ajax\AlertCommand;
 use Drupal\Core\Ajax\CloseDialogCommand;
 use Drupal\Core\Ajax\HtmlCommand;
+use Drupal\Core\EventSubscriber\MainContentViewSubscriber;
 use Drupal\Core\Url;
 use Symfony\Component\HttpFoundation\Request;
 
@@ -117,10 +118,11 @@ public function dialog() {
     $build['link'] = array(
       '#type' => 'link',
       '#title' => 'Link 1 (modal)',
-      '#url' => Url::fromRoute('ajax_test.dialog_contents'),
+      '#url' => Url::fromRoute('ajax_test.dialog_contents', array(), array(
+        'query' => array(MainContentViewSubscriber::WRAPPER_ENVELOPE => 'drupal_modal'),
+      )),
       '#attributes' => array(
         'class' => array('use-ajax'),
-        'data-accepts' => 'application/vnd.drupal-modal',
       ),
     );
 
@@ -133,7 +135,7 @@ public function dialog() {
           'url' => Url::fromRoute('ajax_test.dialog_contents'),
           'attributes' => array(
             'class' => array('use-ajax'),
-            'data-accepts' => 'application/vnd.drupal-modal',
+            'data-dialog-type' => 'modal',
             'data-dialog-options' => json_encode(array(
               'width' => 400,
             ))
@@ -144,7 +146,7 @@ public function dialog() {
           'url' => Url::fromRoute('ajax_test.dialog_contents'),
           'attributes' => array(
             'class' => array('use-ajax'),
-            'data-accepts' => 'application/vnd.drupal-dialog',
+            'data-dialog-type' => 'dialog',
             'data-dialog-options' => json_encode(array(
               'target' => 'ajax-test-dialog-wrapper-1',
               'width' => 800,
@@ -163,7 +165,7 @@ public function dialog() {
           'url' => Url::fromRoute('ajax_test.dialog_form'),
           'attributes' => array(
             'class' => array('use-ajax'),
-            'data-accepts' => 'application/vnd.drupal-modal',
+            'data-dialog-type' => 'modal',
           ),
         ),
         'link6' => array(
@@ -171,7 +173,7 @@ public function dialog() {
           'url' => Url::fromRoute('contact.form_add'),
           'attributes' => array(
             'class' => array('use-ajax'),
-            'data-accepts' => 'application/vnd.drupal-modal',
+            'data-dialog-type' => 'modal',
             'data-dialog-options' => json_encode(array(
               'width' => 800,
               'height' => 500,
@@ -183,7 +185,7 @@ public function dialog() {
           'url' => Url::fromRoute('ajax_test.dialog_contents'),
           'attributes' => array(
             'class' => array('use-ajax'),
-            'data-accepts' => 'application/vnd.drupal-dialog',
+            'data-dialog-type' => 'dialog',
             'data-dialog-options' => json_encode(array(
               'width' => 800,
             ))
diff --git a/core/tests/Drupal/Tests/Core/ContentNegotiationTest.php b/core/tests/Drupal/Tests/Core/ContentNegotiationTest.php
index e411008..d5f3081 100644
--- a/core/tests/Drupal/Tests/Core/ContentNegotiationTest.php
+++ b/core/tests/Drupal/Tests/Core/ContentNegotiationTest.php
@@ -60,9 +60,6 @@ public function testAPriorityFormatIsFound($priority, $format) {
   public function priorityFormatProvider()
   {
     return [
-      ['drupal_dialog', ['format' => 'drupal_dialog', 'mime_type' => 'application/vnd.drupal-dialog']],
-      ['drupal_modal', ['format' => 'drupal_modal', 'mime_type' => 'application/vnd.drupal-modal']],
-      ['drupal_ajax', ['format' => 'drupal_ajax', 'mime_type' => 'application/vnd.drupal-ajax']],
       ['html', ['format' => 'html', 'mime_type' => 'text/html']],
     ];
   }
