【发布时间】:2013-11-27 14:09:05
【问题描述】:
我正在构建一个 Web 应用程序,它是我认识的老师的测试/问题/答案应用程序。其中一项要求是测试必须一次完成……即……不保存并继续。我选择通过使用 jQuery UI 的模式弹出窗口来实现这一点。在开始测试之前,我有一个用于测试的搜索页面和一个模态确认对话框。我遇到的问题是在用户选择继续测试后,它需要重定向到一个新页面,其中将显示第一个问题的模式弹出窗口(之后的每个问题都将通过 AJAX 加载到相同的模式弹出窗口中)。我可以进行搜索以及确认弹出窗口,但我无法弄清楚如何重定向到问题页面。我的 TestingController 中的 Question 操作被调用并且参数正确,但是一旦返回 View,ASP.NET 就会抛出一个异常,告诉我第一个参数为空。以下是控制此行为的 sn-ps:
来自 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 中的 Question 操作(在 VS 中使用断点验证)。 applicationId 和 testId 都填充了正确的值。正确创建了 NextQuestionViewModel 并调用了返回 View(model),但这是我对正在发生的事情迷失的地方。我得到了异常:参数字典包含方法“System.Web.Mvc.ActionResult Question(Int32, Int32)”的不可空类型“System.Int32”的参数“applicantId”的空条目。
但是,如果我直接从 URL 将这些参数添加到查询字符串,页面将加载并且问题的模式弹出窗口会正确显示。这似乎是一个路由问题,但我是 MVC 的新手,我无法理解为什么 TestingController::TakeTest 中的 RedirectToAction 在我可以在 action 方法 Question. /p>
【问题讨论】:
-
等等。当您从头到尾遵循该过程时,是否会在用户在行 'return RedirectToAction("Question", "Testing", ...' 还是第一个问题成功显示并然后抛出异常?
-
它发生在第一个问题显示之前。使用 Fiddler,我发现有 2 次调用 action 方法。第一个来自我的 TakeTest 操作方法,然后是第二个(从 ajax 成功函数中的 window.location.href 行猜测)。第一个具有查询字符串参数,而第二个没有...因此出现错误。我不确定进行此重定向的最佳方式,所以也许这就是我一开始就构建它的方式。非常感谢任何想法。
-
如果我删除 window.location.href 对话框不会关闭,但只会执行第一个请求(使用查询字符串参数),但对话框保持打开状态不会发生重定向。如果我将 $(this).dialog('close') 添加到成功函数,我会收到一个 javascript 错误:“JavaScript 运行时错误:在初始化之前无法调用对话框上的方法;尝试调用方法'close'”不确定如何关闭模式对话框,然后将其重定向到问题页面。
-
对不起...另一个更新:$(this) 是错误的,因为我在成功函数中...更改为 $("#dialog") 确实关闭了对话框,但重定向仍然没有发生...尽管 Fiddler 仍在使用适当的参数显示对测试/问题的调用。
-
这里的问题是您的 MVC 操作正在返回一个重定向到您的
success函数,但您的success函数没有处理它。此外,window.location.href不提供任何查询字符串参数。我会继续发布答案。
标签: jquery asp.net-mvc modal-dialog