diff --git a/module/VuFindSearch/src/VuFindSearch/Backend/Solr/QueryBuilder.php b/module/VuFindSearch/src/VuFindSearch/Backend/Solr/QueryBuilder.php
index 1055b1b9c2cd427a4d404d834fa9e530674296c9..22b59b17840290c3daea98c99d15a1fa7e261fa4 100644
--- a/module/VuFindSearch/src/VuFindSearch/Backend/Solr/QueryBuilder.php
+++ b/module/VuFindSearch/src/VuFindSearch/Backend/Solr/QueryBuilder.php
@@ -154,19 +154,24 @@ class QueryBuilder implements QueryBuilderInterface
                         $params->set('hl.q', $oldString);
                     }
                 }
-            } else {
-                if ($handler->hasDismax()) {
-                    $params->set('qf', implode(' ', $handler->getDismaxFields()));
-                    $params->set('qt', $handler->getDismaxHandler());
-                    foreach ($handler->getDismaxParams() as $param) {
-                        $params->add(reset($param), next($param));
-                    }
-                    if ($handler->hasFilterQuery()) {
-                        $params->add('fq', $handler->getFilterQuery());
-                    }
-                } else {
-                    $string = $handler->createSimpleQueryString($string);
+            } else if ($handler->hasDismax()) {
+                // If we're using extended dismax, we'll miss out on the question
+                // mark fix in createAdvancedInnerSearchString(), so we should
+                // apply it here. If other query munges arise that are valuable
+                // to both dismax and edismax, we should add a wrapper function
+                // around them and call it from here instead of this one very
+                // specific check.
+                $string = $this->fixTrailingQuestionMarks($string);
+                $params->set('qf', implode(' ', $handler->getDismaxFields()));
+                $params->set('qt', $handler->getDismaxHandler());
+                foreach ($handler->getDismaxParams() as $param) {
+                    $params->add(reset($param), next($param));
                 }
+                if ($handler->hasFilterQuery()) {
+                    $params->add('fq', $handler->getFilterQuery());
+                }
+            } else {
+                $string = $handler->createSimpleQueryString($string);
             }
         }
         $params->set('q', $string);
@@ -362,6 +367,28 @@ class QueryBuilder implements QueryBuilderInterface
         }
     }
 
+    /**
+     * If the query ends in a non-escaped question mark, the user may not really
+     * intend to use the question mark as a wildcard -- let's account for that
+     * possibility.
+     *
+     * @param string $string Search query to adjust
+     *
+     * @return string
+     */
+    protected function fixTrailingQuestionMarks($string)
+    {
+        if (substr($string, -1) == '?' && substr($string, -2) != '\?') {
+            // Make sure all question marks are properly escaped (first unescape
+            // any that are already escaped to prevent double-escapes, then escape
+            // all of them):
+            $strippedQuery
+                = str_replace('?', '\?', str_replace('\?', '?', $string));
+            $string = "({$string}) OR (" . $strippedQuery . ")";
+        }
+        return $string;
+    }
+
     /**
      * Return advanced inner search string based on input and handler.
      *
@@ -386,17 +413,8 @@ class QueryBuilder implements QueryBuilderInterface
             return $string;
         }
 
-        // If the query ends in a non-escaped question mark, the user may not really
-        // intend to use the question mark as a wildcard -- let's account for that
-        // possibility
-        if (substr($string, -1) == '?' && substr($string, -2) != '\?') {
-            // Make sure all question marks are properly escaped (first unescape
-            // any that are already escaped to prevent double-escapes, then escape
-            // all of them):
-            $strippedQuery
-                = str_replace('?', '\?', str_replace('\?', '?', $string));
-            $string = "({$string}) OR (" . $strippedQuery . ")";
-        }
+        // Account for trailing question marks:
+        $string = $this->fixTrailingQuestionMarks($string);
 
         return $handler
             ? $handler->createAdvancedQueryString($string, false) : $string;
diff --git a/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/Solr/QueryBuilderTest.php b/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/Solr/QueryBuilderTest.php
index cf889b9425c26f807b38b13df41796964b7f374b..2ea5b62f11576630730ea79612837a95f0882a4b 100644
--- a/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/Solr/QueryBuilderTest.php
+++ b/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/Solr/QueryBuilderTest.php
@@ -129,6 +129,34 @@ class QueryBuilderTest extends \VuFindTest\Unit\TestCase
         }
     }
 
+    /**
+     * Test generation with a query handler with edismax
+     *
+     * @return void
+     */
+    public function testQueryHandlerWithEdismax()
+    {
+        // Set up an array of expected inputs and outputs:
+        // @codingStandardsIgnoreStart
+        $tests = [
+            ['this?', '(this?) OR (this\?)'],// trailing question mark
+        ];
+        // @codingStandardsIgnoreEnd
+
+        $qb = new QueryBuilder(
+            [
+                'test' => ['DismaxHandler' => 'edismax', 'DismaxFields' => ['foo']]
+            ]
+        );
+        foreach ($tests as $test) {
+            list($input, $output) = $test;
+            $q = new Query($input, 'test');
+            $response = $qb->build($q);
+            $processedQ = $response->get('q');
+            $this->assertEquals($output, $processedQ[0]);
+        }
+    }
+
     /**
      * Test that the appropriate handler gets called for a quoted search when exact
      * settings are enabled.