我有一个web应用程序,我正在构建一个测试/问题/答案应用程序,我认识一位老师。其中一个要求是测试必须在一次会议中完成......即......不保存并继续。我选择通过使用jQuery UI的模式弹出窗口来实现这一点。在测试开始前,我有一个测试搜索页面和一个模态确认对话框。我遇到的问题是在用户选择继续测试之后,它需要重定向到一个新页面,其中第一个问题将显示模式弹出窗口(之后的每个问题将通过AJAX加载到相同的模式弹出窗口中)。我有搜索工作,以及确认弹出窗口,但我无法弄清楚如何重定向到问题页面。我的TestingController中的Question操作被调用并且参数是正确的,但是一旦返回View,ASP.NET将引发一个异常,告诉我第一个参数为null。以下是控制此行为的片段:从ASP.NET MVC中成功的AJAX调用重定向
从Search.cshtml(这个div是模态确认弹出):
<div id="dialog" title="Confirm Test">
<p>
<span class="ui-icon ui-icon-alert" style="float:left; margin:0 7px 20px 0;"></span>Are you sure you want to take the selected test?
</p>
</div>
@section scripts
{
<script type="text/javascript">
$(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');
}
}
});
});
</script>
}
从TestingController:
[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<NextQuestionViewModel>(nextQuestion);
model.ApplicantId = applicantId;
model.QuestionNumber = (nextQuestion.ApplicantTestAnswers.Count + 1);
return View(model);
}
来自Question.cshtml:
@Html.HiddenFor(x => x.ApplicantId, new { id = "applicantId" })
@Html.HiddenFor(x => x.TestId, new { id = "testId" })
<div id="dialog" title="Question: @Model.QuestionNumber">
@Html.Partial("_NextQuestionPartial", Model)
</div>
@section scripts
{
<script type="text/javascript">
$(document).ready(function() {
$("#dialog").dialog({
dialogClass: "no-close",
autoOpen: true,
modal: true,
resizable: false,
height: 400,
buttons: {
'Next': function() {
}
}
});
});
</script>
}
从_NextQuestionPartial.cshtml:
@Ajax.BeginForm("Question", "Testing", new AjaxOptions { HttpMethod = "POST", InsertionMode = InsertionMode.Replace, UpdateTargetId = "nextQuestionContainer" })
{
<fieldset>
<legend>Question # @Model.QuestionNumber</legend>
<div id="nextQuestionContainer">
<p>Q: @Model.QuestionText</p>
<ul>
@foreach (var answer in Model.QuestionAnswers)
{
<li>
@answer.Answer
</li>
}
</ul>
</div>
</fieldset>
}
在Search.cshtml模态确认弹出罚款和确认按钮调用TestingController问题的行动(与断点VS验证)。 applicantId和testId都填充了正确的值。 NextQuestionViewModel被正确创建并且返回View(模型)被调用,但是这正是我所迷失的事情发生的地方。我得到了这个异常:参数字典包含一个空方法'System.Web.Mvc.ActionResult Question(Int32,Int32)'的非空类型'System.Int32'的参数'applicantId'的空项。
但是,如果我直接从URL中将这些参数添加到querystring中,页面将加载并且问题的模式弹出窗口会正确显示。看起来这是一个路由问题,但我是MVC的新手,我无法理解为什么TestingController :: TakeTest中的RedirectToAction正在抛出有关applicantId的此异常,因为我可以在操作方法Question中看到它的值。
等待。当你从头到尾地执行这个过程时,是否会发生异常*只是在用户在第**行确认测试后返回RedirectToAction(“Question”,“Testing”,...'**或者第一个问题成功显示并*然后*抛出异常? – William
它发生在第一个问题显示之前。使用Fiddler,我已经确定有2个调用操作方法。第一个来自我的TakeTest操作方法,然后是第二个(从ajax成功函数中的window.location.href行猜测)。第一个参数是querystring,第二个参数不是......因此错误。我不确定最好的方法来做这个重定向,所以也许它 – user1011627
如果我删除了window.location.href,那么对话框并没有关闭,但是只有第一个请求被执行(带有查询字符串参数),但是对话框保持不变打开重定向不会发生。如果我将$(this).dialog('close')添加到成功函数中,我得到一个javascript错误:“JavaScript运行时错误:无法在初始化之前调用对话框上的方法;试图调用方法'关闭'” 确定如何关闭模式对话框,然后将其重定向到问题页面。 – user1011627