title: Redirect from successful AJAX call in ASP.NET MVC
body: <p>I have a web application that I am building that is a test/question/answer app for a teacher I know.  One of the requirements is that the test must be completed in one sitting...ie...no save and continue.  I chose to implement this via a modal popup using jQuery UI.  I have a search page for the test to take and a modal confirmation dialog before the test can be started.  The problem I have is after the user elects to continue the test, it needs to redirect to a new page where a modal popup will be displayed with the first question (each question after will be loaded in same modal popup via AJAX).  I have the search working, along with the confirmation popup, but I cannot figure out how to redirect to the question page.  The Question action in my TestingController gets called and the parameters are correct, but once the View is returned, ASP.NET throws an exception telling me that the first parameter is null.  Below are the snippets that control this behavior:</p>
  
  <p><strong>From Search.cshtml (this div is the modal confirmation popup):</strong></p>
  
  <pre><code> &lt;div id="dialog" title="Confirm Test"&gt;
  
          &lt;p&gt;
              &lt;span class="ui-icon ui-icon-alert" style="float:left; margin:0 7px 20px 0;"&gt;&lt;/span&gt;Are you sure you want to take the selected test?
          &lt;/p&gt; 
  
      &lt;/div&gt;
  
  @section scripts
  {
      &lt;script type="text/javascript"&gt;
  
          $(document).ready(function () {
  
              $(".takeTest").click(function (e) {
  
                  e.preventDefault();
  
                  var testId = $(this).data("test-id");
                  $("#selectedTestId").val(testId);
  
                  $("#dialog").dialog("open");
  
              });
  
              $("#dialog").dialog({
                  dialogClass: "no-close",
                  autoOpen: false,
                  modal: true,
                  resizable: false,
                  height: 180,
                  buttons: {
                      'Confirm': function () {
  
                          var appId = $("#applicantId").val();
                          var id = $("#selectedTestId").val();
  
                          $.ajax({
                              url: "/Testing/TakeTest/",
                              data: { applicantId: appId, testId: id },
                              type: "POST",
                              success: function (results) {
                                  window.location.href = "/Testing/Question/";
                              }
                          });
                      },
                      'Cancel': function () {
                          $(this).dialog('close');
                      }
                  }
              });
          });
  
      &lt;/script&gt;
  }
  </code></pre>
  
  <p><strong>From the TestingController:</strong></p>
  
  <pre><code>        [HttpPost]
          public ActionResult TakeTest(int applicantId, int testId)
          {
              try
              {
                  ApplicantTest test = TestingRepository.GetInstance().TakeTest(applicantId, testId);
                  return RedirectToAction("Question", "Testing", new { applicantId = applicantId, testId = testId });
              }
              catch
              {
                  return RedirectToAction("Search", "Testing");
              }
          }
  
  
          [HttpGet]
          public ActionResult Question(int applicantId, int testId)
          {
              Question nextQuestion = TestingRepository.GetInstance().GetNextQuestion(applicantId, testId);
              NextQuestionViewModel model = AutoMapper.Mapper.Map&lt;NextQuestionViewModel&gt;(nextQuestion);
              model.ApplicantId = applicantId;
              model.QuestionNumber = (nextQuestion.ApplicantTestAnswers.Count + 1);
              return View(model);
          }
  </code></pre>
  
  <p><strong>From Question.cshtml:</strong></p>
  
  <pre><code>@Html.HiddenFor(x =&gt; x.ApplicantId, new { id = "applicantId" })
  @Html.HiddenFor(x =&gt; x.TestId, new { id = "testId" })
  
  &lt;div id="dialog" title="Question: @Model.QuestionNumber"&gt;
  
      @Html.Partial("_NextQuestionPartial", Model)
  
  &lt;/div&gt;
  
  @section scripts
  {
      &lt;script type="text/javascript"&gt;
  
          $(document).ready(function () {
  
              $("#dialog").dialog({
                  dialogClass: "no-close",
                  autoOpen: true,
                  modal: true,
                  resizable: false,
                  height: 400,
                  buttons: {
                      'Next': function () {
  
  
                      }
                  }
              });
  
  
          });
  
      &lt;/script&gt;
  }
  </code></pre>
  
  <p><strong>From _NextQuestionPartial.cshtml:</strong></p>
  
  <pre><code>@Ajax.BeginForm("Question", "Testing", new AjaxOptions { HttpMethod = "POST", InsertionMode = InsertionMode.Replace, UpdateTargetId = "nextQuestionContainer" })
  {
      &lt;fieldset&gt;
          &lt;legend&gt;Question # @Model.QuestionNumber&lt;/legend&gt;
  
          &lt;div id="nextQuestionContainer"&gt;
              &lt;p&gt;Q:  @Model.QuestionText&lt;/p&gt;
              &lt;ul&gt;
                  @foreach (var answer in Model.QuestionAnswers)
                  {
                      &lt;li&gt;
                          @answer.Answer
                      &lt;/li&gt;
                  }
              &lt;/ul&gt;
          &lt;/div&gt;
      &lt;/fieldset&gt;
  }
  </code></pre>
  
  <p>The modal confirmation in Search.cshtml pops up fine and the confirm button calls the Question action in TestingController (verified with breakpoint in VS).  applicantId and testId are both populated with the correct values.  The NextQuestionViewModel is created correctly and the return View(model) is called, but this is where I get lost on what is happening.  I get the exception: The parameters dictionary contains a null entry for parameter 'applicantId' of non-nullable type 'System.Int32' for method 'System.Web.Mvc.ActionResult Question(Int32, Int32)'.</p>
  
  <p>However, if I add these parameters to the querystring directly from the URL, the page will load and the modal popup for the question gets displayed properly.  It seems like this is a routing issue, but I am new to MVC and I am having trouble understanding why the RedirectToAction in TestingController::TakeTest is throwing this exception about applicantId when I can see it with a value in the action method Question.</p>