我的情况如下; “调查”包含“问题”类型的列表; “问题”由一个名为“Text”的id和字符串组成。以下是类定义:
public class Survey
{
public int SurveyId { get; set; }
public string Title { get; set; }
public List<Question> Questions { get; set; }
public Survey()
{
this.Questions = new List<Question>();
}
}
public class Question
{
public int QuestionId { get; set; }
public string QuestionText { get; set; }
public int OwningSurveyId { get; set; }
}
我希望能够从特定调查的页面链接创建一个新问题(工作正常),但是当提交问题表单时,我想做两件事; 1)确保正确设置OwningSurveyId,并2)将问题添加到Survey.Questions列表。
我愿意接受任何解决方案以获得此功能 - 我采取的方法可能不是最好的。我决定将调查对象传递给问题的创建表单,以便在提交表单时,表单包含两个对象,因此我可以正确执行上述任务(1&amp; 2)。
我在QuestionController中设置了Create Question页面,如下所示:
// GET: /Question/Create
public ActionResult Create(Survey OwningSurvey)
{
return View(OwningPulse);
}
[HttpPost]
public ActionResult Create(Pulse OwningPulse, Question NewQuestion)
{
ModelState["OwningSurveyId"].Errors.Clear();
if (ModelState.IsValid)
{
OwningPulse.Questions.Add(NewQuestion);
db.Questions.Add(NewQuestion);
db.SaveChanges();
return RedirectToAction("Index", "Survey");
}
return View(OwningSurvey);
}
并且问题的Create.cshtml文件具有以下内容:
@model MoodTool.Interface.Models.Survey
@{
ViewBag.Title = "Create";
var Question = new MoodTool.Interface.Models.Question();
Question.OwningPulseId = Model.SurveyId;
}
@using (Html.BeginForm("Create", "Question", "{NewQuestion}", FormMethod.Post, new { NewQuestion = Question }))
{... code follows
我遇到的问题是.cshtml文件中“Model”的值为null,因此页面崩溃。问题控制器的Create方法(“GET”版本)中OwningSurvey的值也为null。
有人能引导我朝正确的方向前进吗?我意识到我可能正在做一些重大错误(设计模式),或者做了一个简单的语法错误,但我是MVC的新手并绕圈子。
由于
答案 0 :(得分:1)
您是否正在为调查行动中添加问题的调查加载模型?如果没有,那么这就是你的模型为空的原因。根据我在这里看到的内容,这只是我的猜测。 RedirectToActions不加载模型,因此您必须将其放入TempData并在重定向的操作中重新加载。
第二部分
在第一部分中,您将创建问题并重定向到用于调查的索引操作。
OwningPulse.Questions.Add(NewQuestion);
db.Questions.Add(NewQuestion);
db.SaveChanges();
return RedirectToAction("Index", "Survey");
进入索引操作后,您需要重新加载首先放置问题的调查,然后将其加载到模型中以传递给视图。通过将id传递给action方法,使用上面的lavriks方法,然后可以从db获取该调查并将其传递给为视图定义的模型中的视图。
public ActionResult Index(int id)
{
// assuming you have some built in functionality to retrieve the survey information from the db through the constructor given an id
Survey s1 = new survey(id);
// some of this is pseudo code, assumes you have a model defined called survey for the view using it
// Return view with model.
return View( "Survey" , s1 );
}
当我谈到tempdata而不是将ID传递给action方法并在视图的action方法中再次查找时,可以将对象存储在tempdata中
// save data to survey in teh create action method
TempData["survey"] = survey
然后在调查的默认索引操作方法中调用tempdata中的调查并将其发送到视图。
Survey s1 = (Survey)Tempdata["survey"];
return View ("Survey", s1);
再一些是伪代码而不是完全完整但它应该指向正确的方向。这两种方法都有它们的上下方,但取决于应用程序,对象的大小,有多少人正在使用hte页面等,你可以使用或者。
答案 1 :(得分:1)
这里最好的方法之一是Post-Redirect-Get模式。您只需发布带有调查ID的问题表单。在控制器中,您可以尝试按ID读取调查并检查它是否存在。然后添加问题并保存调查。例如,重定向到Survey GET操作。它将显示包括新添加的问题。 此外,你只会在这里发布问题和调查ID - 你不需要在这里更多地讨论。您不会通过发布一些不必要的数据来更改Survey - 所以它也更安全一些。
EDIT。
例如。
// GET: /Question/Create
public ActionResult Create(int surveyId)
{
return View(new Question(){OwningSurveyId = surveyId });
}
[HttpPost]
public ActionResult Create(Question newQuestion)
{
if (ModelState.IsValid)
{
//I've never used EntityFramework so just a pseudo code here
var survey = db.Surveys.Get(newQuestion.OwningSurveyId);
if(survey != null)
{
survey.Questions.Add(newQuestion);
db.Surveys.Save(survey);
db.SaveChanges();
//If you want to open specific survey,
//you can pass it's Id to read it in Survey index action
return RedirectToAction("Index", "Survey", {Id = survey.Id});
}
}
return View(newQuestion);
}
查看创建问题
@model MoodTool.Interface.Models.Question
@{
ViewBag.Title = "Create";
}
@using (Html.BeginForm("Create", "Question", FormMethod.Post))
{
@Html.HiddenFor(x => x.OwningSurveyId)
@Html.EditorFor(x => x.QuestionText)
//etc.
}