使用mvc中动作之间的值来查看模型
本文关键字:模型 之间 mvc 使用 | 更新日期: 2023-09-27 17:49:54
我有一个问题,我不知道如何解决。请注意,我是MVC的新手。
我正在设计一个有8个问题的调查。我在一个视图中创建每个问题。
我需要的是保持我的视图之间的数据,但我失去了数据,即使我通过它们作为一个单一的视图模型。
请帮…
我有以下ViewModel
public class SurveyViewModelNew
{
public string description { get; set; }
public Question1ViewModel QuestionText1 { get; set; }
public Question2ViewModel QuestionText2 { get; set; }
public Question3ViewModel QuestionText3 { get; set; }
public Question4ViewModel QuestionText4 { get; set; }
public Question5ViewModel QuestionText5 { get; set; }
public Question6ViewModel QuestionText6 { get; set; }
public Question7ViewModel QuestionText7 { get; set; }
public Question8ViewModel QuestionText8 { get; set; }
}
和每个问题的视图模型:
public class Question1ViewModel
{
public string QuestionText { get; set; }
public AnswerViewModel Answers { get; set; }
}
和我这是我的视图的样子?
@model survey.Models.SurveyViewModelNew
@using (Html.BeginForm("QuestionOneNext", "CreateSurveyStep2", FormMethod.Post, new { @class = "form-horizontal", role = "form", Model = Model }))
{
<div class="form-horizontal">
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="form-group">
@Html.Label("Question 1: What question would you like to ask", htmlAttributes: new { @class = "control-label col-md-4" })
<div class="col-md-5">
@Html.EditorFor(model => model.QuestionText1.QuestionText, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.QuestionText1.QuestionText, "", new { @class = "text-danger" })
</div>
</div>
<br/>
<br/>
<div class="form-group">
@Html.Label("Answer A", htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.QuestionText1.Answers.AnswerTextA, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.QuestionText1.Answers.AnswerTextA, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.Label("Answer B", htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.QuestionText1.Answers.AnswerTextB, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.QuestionText1.Answers.AnswerTextB, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.Label("Answer C", htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.QuestionText1.Answers.AnswerTextC, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.QuestionText1.Answers.AnswerTextC, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.Label("Answer D", htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.QuestionText1.Answers.AnswerTextD, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.QuestionText1.Answers.AnswerTextD, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.Label("Answer E", htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.QuestionText1.Answers.AnswerTextE, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.QuestionText1.Answers.AnswerTextE, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.Label("Answer F", htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.QuestionText1.Answers.AnswerTextF, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.QuestionText1.Answers.AnswerTextF, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.Label("Answer G", htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.QuestionText1.Answers.AnswerTextG, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.QuestionText1.Answers.AnswerTextG, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.Label("Answer H", htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.QuestionText1.Answers.AnswerTextH, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.QuestionText1.Answers.AnswerTextH, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.Label("Answer K", htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.Label("Not applicable", htmlAttributes: new { @class = "control-label col-md-2" })
</div>
</div>
<div class="form-group">
@Html.Label("Answer L", htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.Label("Flag inappropriate question/refuse to answer", htmlAttributes: new { @class = "control-label col-md-5" })
</div>
</div>
<br/>
<br/>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Previous Step" class="btn btn-info" name="direction"/>
<input type="submit" value="Add a New Question to this survey" class="btn btn-danger" name="direction" />
<input type="submit" value="Countinue to submit this survey" class="btn btn-success" name="direction" />
</div>
</div>
</div>
}
,这是我的控制器的样子:
[HttpPost]
public ActionResult QuestionOneNext(SurveyViewModelNew surveyViewModel, string direction)
{
if (direction == "Countinue to submit this survey")
return RedirectToAction("Edit", "something", surveyViewModel);
if (direction == "Add a New Question to this survey")
{
return View("QuestionTwo", surveyViewModel);
//return RedirectToAction("QuestionTwo", "CreateSurveyStep2", surveyViewModel);
}
if (direction == "Previous Step")
return RedirectToAction("Index", "CreateSurveyStep1", surveyViewModel);
return View();
}
[HttpPost]
public ActionResult QuestionTwo(SurveyViewModelNew surveyViewModel, string direction)
{
if (direction == "Countinue to submit this survey")
{
return RedirectToAction("Edit", "NutStorage", surveyViewModel);
}
if (direction == "Add a New Question to this survey")
{
//return RedirectToAction("QuestionThree", "CreateSurveyStep2", surveyViewModel);
return View("QuestionThree", "CreateSurveyStep2", surveyViewModel);
}
if (direction == "Previous Step")
return RedirectToAction("QuestionOne", "CreateSurveyStep2", surveyViewModel);
return View();
}
结果是当我在控制器中执行"QuestionTwo"动作时,我丢失了第一个问题的答案。
我通过使用TemData修复了这个问题,以下是我的固定控制器:
[HttpGet]
public ActionResult QuestionOne(SurveyViewModelNew surveyViewModel)
{
var currentSurveyViewModel = (SurveyViewModelNew)TempData["SurveyView"];
if (currentSurveyViewModel != null)
{
if (currentSurveyViewModel.description != null)
{
surveyViewModel.description = currentSurveyViewModel.description;
}
if (currentSurveyViewModel.QuestionText1 != null)
{
surveyViewModel.QuestionText1 = currentSurveyViewModel.QuestionText1;
}
if (currentSurveyViewModel.QuestionText2 != null)
{
surveyViewModel.QuestionText2 = currentSurveyViewModel.QuestionText2;
}
if (currentSurveyViewModel.QuestionText3 != null)
{
surveyViewModel.QuestionText3 = currentSurveyViewModel.QuestionText3;
}
if (currentSurveyViewModel.QuestionText4 != null)
{
surveyViewModel.QuestionText4 = currentSurveyViewModel.QuestionText4;
}
if (currentSurveyViewModel.QuestionText5 != null)
{
surveyViewModel.QuestionText5 = currentSurveyViewModel.QuestionText5;
}
if (currentSurveyViewModel.QuestionText6 != null)
{
surveyViewModel.QuestionText6 = currentSurveyViewModel.QuestionText6;
}
if (currentSurveyViewModel.QuestionText7 != null)
{
surveyViewModel.QuestionText7 = currentSurveyViewModel.QuestionText7;
}
TempData["SurveyView"] = surveyViewModel;
}
if (surveyViewModel.description!= null)
{
surveyViewModel.description = surveyViewModel.description;
TempData["SurveyView"] = surveyViewModel;
}
return View("QuestionOne", surveyViewModel);
}
[HttpGet]
public ActionResult QuestionOneNext(SurveyViewModelNew surveyViewModel, string direction)
{
var currentSurveyViewModel = (SurveyViewModelNew)TempData["SurveyView"];
if (currentSurveyViewModel != null)
{
if (currentSurveyViewModel.description != null)
{
surveyViewModel.description = currentSurveyViewModel.description;
}
if (currentSurveyViewModel.QuestionText1 != null)
{
surveyViewModel.QuestionText1 = currentSurveyViewModel.QuestionText1;
}
if (currentSurveyViewModel.QuestionText2 != null)
{
surveyViewModel.QuestionText2 = currentSurveyViewModel.QuestionText2;
}
if (currentSurveyViewModel.QuestionText3 != null)
{
surveyViewModel.QuestionText3 = currentSurveyViewModel.QuestionText3;
}
if (currentSurveyViewModel.QuestionText4 != null)
{
surveyViewModel.QuestionText4 = currentSurveyViewModel.QuestionText4;
}
if (currentSurveyViewModel.QuestionText5 != null)
{
surveyViewModel.QuestionText5 = currentSurveyViewModel.QuestionText5;
}
if (currentSurveyViewModel.QuestionText6 != null)
{
surveyViewModel.QuestionText6 = currentSurveyViewModel.QuestionText6;
}
if (currentSurveyViewModel.QuestionText7 != null)
{
surveyViewModel.QuestionText7 = currentSurveyViewModel.QuestionText7;
}
}
if (direction == "Countinue to submit this survey")
return View("something", surveyViewModel);
else if (direction == "Add a New Question to this survey")
{
TempData["SurveyView"] = surveyViewModel;
return View("QuestionTwo", surveyViewModel);
}
else if (direction == "Previous Step")
{
TempData["SurveyView"] = surveyViewModel;
return View("Index", surveyViewModel);
}
else return View();
}
不是用这种方式来对抗MVC框架,这里有一些其他的方法可以让更有意义。
1)考虑在访问数据库时保存答案
该记录可能是某种临时记录,直到问卷结束时用户进行最终提交时才被认为是"真实的"。
2)如果问题数据不是太大,在一个视图中呈现每个问题在它自己的部分(一个div,一个选项卡控件),并在javascript中处理按钮点击时在部分之间切换。您可以使用现有的ViewModel将所有问题放入视图中,并在最后将它们全部发布和保存。让它成为一个问题列表,而不是8个问题属性,你甚至可以在视图中有一个for循环,为每个问题呈现一个部分。局部可以处理next和previous按钮等
要将完整的模型从一个页面传递到下一个页面,您必须确保模型的所有属性都是表单的一部分,并在每个表单提交操作返回到服务器时被发送回来。
要实现这一点,您需要在视图中使用@HTML创建隐藏的表单字段。包含模型的所有数据,即使您没有在特定页面上向用户显示它。
每次发出同步HTTP请求时,实际上都是在重新加载相同的页面,只是返回值不同而已。如果您希望数据持久化,那么您将受益于更多地了解异步请求(AJAX),它可以在不重定向的情况下发送/接收信息……否则,您需要持久化问题1的答案,并将其与问题2的视图一起返回…然后对于问题3,您需要确保问题1和问题2是持久化的,并返回它们的值以及问题3的上下文。
你"可以"像前面提到的那样使用隐藏字段,但你应该把这看作是一个学习新东西和有用东西的机会。使用隐藏字段已经落伍了,而且真的真的过时了。
选项1:TempData
同样的问题在这里解决:我们可以在RedirectToAction中传递模型作为参数吗?
问题是你使用了RedirectToAction。你不能这样传递模型,只能传递基本类型。您需要在此过程中使用TempData:
[HttpPost]
public ActionResult QuestionOneNext(SurveyViewModelNew surveyViewModel, string direction)
{
var currentSurveyViewModel = surveyViewModel ?? (SurveyViewModel)TempData["SurveyView"];
if (direction == "Countinue to submit this survey")
{
TempData["SurveyView"] = currentSurveyViewModel;
return RedirectToAction("Edit", "something", null);
}
if (direction == "Add a New Question to this survey")
{
return View("QuestionTwo", currentSurveyViewModel);
//return RedirectToAction("QuestionTwo", "CreateSurveyStep2", surveyViewModel);
}
if (direction == "Previous Step")
{
TempData["SurveyView"] = currentSurveyViewModel;
return RedirectToAction("Index", "CreateSurveyStep1", null);
}
return View();
}
[HttpPost]
public ActionResult QuestionTwo(SurveyViewModelNew surveyViewModel, string direction)
{
var currentSurveyViewModel = surveyViewModel ?? (SurveyViewModel)TempData["SurveyView"];
if (direction == "Countinue to submit this survey")
{
TempData["SurveyView"] = currentSurveyViewModel ;
return RedirectToAction("Edit", "NutStorage", null);
}
if (direction == "Add a New Question to this survey")
{
//return RedirectToAction("QuestionThree", "CreateSurveyStep2", surveyViewModel);
return View("QuestionThree", "CreateSurveyStep2", currentSurveyViewModel );
}
if (direction == "Previous Step")
{
TempData["SurveyView"] = currentSurveyViewModel ;
return RedirectToAction("QuestionOne", "CreateSurveyStep2", null);
}
return View();
}
选项2:RouteValueDictionary
使用复杂类型还有另一个选择,那就是使用RouteValueDictionary。在RedirectToAction
中传递对象对于你的RedirectToAction调用,一般的想法是这样做:return RedirectToAction("Edit", "NutStorage", new RouteValueDictionary(surveyViewModel));