我在C#中使用ASP.NET MVC3。
我的数据库中有一个包含问题的表。管理员可以添加新问题,编辑问题等。
我有另一张表格,其中包含答案的问题(以及答案)。
示例:
问题表:
QuestionId ..........问题
....... 1 ..............你好吗?
....... 2 .........为什么天蓝色?
在我看来,我说“对于每个问题,打印问题并提供一个文本区域来回答问题”
然后我想说“当他们提交时,将每个问题和答案对保存到问答表”
答案表:
AnswerId ........问题........回答
...... 1 .........你好吗?......我没事。
...... 2 ....为什么天蓝色?...因为
问题是存在任意/可变数量的问题,因此存在任意数量的文本区域。如何将该信息传递给Post动作?
修改
这是我在Xander的推荐之后的观点
@using (Html.BeginForm("QuestionsAndAnswers", "Product"))
{
int i = 0;
foreach (var m in Model.Questions)
{
i++;
<div>@m.Body</div>
@Html.TextArea(string.Format("textareas[{0}]", i))
<br />
}
<input type="submit" value="Save"/>
@Html.ActionLink("Cancel", "Index", "Home");
}
答案 0 :(得分:2)
使用您的观点......
@using (Html.BeginForm("QuestionsAndAnswers", "Product"))
{
foreach (var m in Model.Questions)
{
<div class="formfields">
<input type="hidden" name="QuestionId" id="QuestionId" value="@m.QuestionId" />
<div>@m.Body</div>
<textarea name="Answer" id="Answer"></textarea>
</div>
}
<input type="submit" value="Save"/>
@Html.ActionLink("Cancel", "Index", "Home");
}
这是Jquery ....
<script type="text/javascript">
$.fn.serializeObject = function () {
var o = {};
var a = this.serializeArray();
$.each(a, function () {
if (o[this.name]) {
if (!o[this.name].push) {
o[this.name] = [o[this.name]];
}
o[this.name].push(this.value || '');
} else {
o[this.name] = this.value || '';
}
});
return o;
};
$(document).ready(function () {
$("#Submit").click(function () {
var QuestionAnswerArray = [];
var QuestionAnswerLength = $(".formfield").length;
$(".formfield").each(function (i) {
var test = $(this).find("textarea, input").serializeObject()
QuestionAnswerArray.push(test);
if ((i + 1) == QuestionAnswerLength) {
$.ajax({
type: 'POST',
url: '/../Product/QuestionsAndAnswers',
data: JSON.stringify(QuestionAnswerArray),
contentType: 'application/json; charset=utf-8',
dataType: 'json',
success: function (return_flag) {
if (return_flag == true) {
alert("Question and Answers Saved Succesfully!");
} else {
alert("Error Occured");
}
}
});
}
});
});
});
</script>
你在Controller中的行动......
[HttpPost]
public ActionResult QuestionsAndAnswers(Answers[] answers)
{
foreach (var item in answers)
{
// do whatever you want here
}
return View();
}
答案 1 :(得分:1)
型号:
public class Question
{
public int Id { get; set; }
public string QuestionText { get; set; }
}
public class Answer
{
public int Id { get; set; }
public string QuestionText { get; set; }
public string AnswerText { get; set; }
}
视图模型:
public class AnswersViewModel
{
public IList<Answer> Answers { get; set; }
}
控制器:
public class AnswersController : Controller
{
QuestionRepository _questionRepository = new QuestionRepository();
public ActionResult Index()
{
AnswersViewModel model = new AnswersViewModel();
model.Answers = new List<Answer>();
IEnumerable<Question> questions = _questionRepository.GetRandomQuestions();
foreach (Question question in questions)
{
model.Answers.Add(new Answer() { QuestionText = question.QuestionText });
}
return View(model);
}
[HttpPost]
public ActionResult Index(AnswersViewModel model)
{
//the model will be properly bound here
return View(model);
}
}
查看/答案/ Index.cshtml
@model MvcApplication1.Models.AnswersViewModel
@{
ViewBag.Title = "Index";
}
@using (Html.BeginForm("Index", "Answers", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
@Html.EditorFor(x => x.Answers)
<input name="submit" type="submit" value="Submit" />
}
查看/答案/ EditorTemplates / Answer.cshtml
@model MvcApplication1.Models.Answer
@Html.HiddenFor(x => x.Id)
@Html.HiddenFor(x => x.QuestionText)
@Html.DisplayFor(x => x.QuestionText)
<br />
@Html.TextAreaFor(x => x.AnswerText)
<br />
修改强>
我更新了答案,使其更加清晰。
答案 2 :(得分:1)
我们可以编写控制器来接收来自模型或视图模型的数组,但是数组不是ORM友好的(如果您计划直接使用域模型进行查看)。考虑到这一点,我们的Controller的视图将在IList
上运行; IList
是灵活的,与数组不同,它不受元素数量的限制;与数组相比,IList是ORM就绪的。
我们应该做的唯一调整就是考虑; HTML或者更确切地说是javascript,没有列表的概念,它只能使用数组或关联数组。承认此限制,我们会将这些项目从List<ClassType>
发送到javascript友好的数组。
最后,当我们提交时,我们友好的邻居ASP.NET MVC将为我们处理这些问题,即它可以根据HTML / javascript中提交的数组自动填充我们的List<ClassType>
变量,即有我们不需要迭代Request.Form
,不需要手动填充,我们的代码操作的所有东西都是以Model / ViewModel为中心的,因为它们应该是。 ASP.NET MVC程序员的生活很精彩不是吗? ; - )
完整的代码如下:
型号:
namespace SoQna.Models
{
public class Question
{
public int QuestionId { get; set; }
public string QuestionText { get; set; }
}
public class Answer
{
public int AnswerId { get; set; }
public Question Question { get; set; }
public string AnswerText { get; set; }
}
}
视图模型:
using System.Collections.Generic;
namespace SoQna.ViewModels
{
public class QnaViewModel
{
public IList<AnswerToQuestion> Answers { get; set; }
}
public class AnswerToQuestion
{
public int ToQuestionId { get; set; }
public string QuestionText { get; set; }
public string AnswerText { get; set; }
}
}
控制器:
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
namespace SoQna.Controllers
{
public class HomeController : Controller
{
IList<SoQna.Models.Question> _qnaRepo = new List<SoQna.Models.Question>
{
new SoQna.Models.Question { QuestionId = 1,
QuestionText =
"Why is there a proliferation of different kind of ORMs?"
},
new SoQna.Models.Question {
QuestionId = 2, QuestionText = "How are you?"
},
new SoQna.Models.Question {
QuestionId = 3, QuestionText = "Why the sky is blue?"
},
new SoQna.Models.Question {
QuestionId = 4, QuestionText = "Why is MVC the bees knees?"
},
};
public ActionResult Index()
{
var qna = new SoQna.ViewModels.QnaViewModel {
Answers = new List<SoQna.ViewModels.AnswerToQuestion>()
};
foreach (var question in _qnaRepo)
{
if (question.QuestionId == 1) continue; // subjective :-)
qna.Answers.Add(
new SoQna.ViewModels.AnswerToQuestion {
ToQuestionId = question.QuestionId,
QuestionText = question.QuestionText,
AnswerText = "Put your answer here"
}
);
}
return View(qna);
}
[HttpPost]
public ViewResult SubmitAnswers(SoQna.ViewModels.QnaViewModel a)
{
foreach (var answer in a.Answers)
{
answer.QuestionText = _qnaRepo.Single(x =>
x.QuestionId == answer.ToQuestionId).QuestionText;
}
return View(a);
}
}//HomeController
}//namespace
查看主页/索引
@model SoQna.ViewModels.QnaViewModel
@{
ViewBag.Title = "Index";
}
<h2>Hahah</h2>
@using (Html.BeginForm("SubmitAnswers", "Home"))
{
int i = 0;
foreach (var answer in Model.Answers)
{
@: Question #@(answer.ToQuestionId) <br />
@Html.Hidden("Answers[" + i + "].ToQuestionId", answer.ToQuestionId)
@Html.Label("Answers[" + i + "].QuestionText", answer.QuestionText)
@*
to save bandwidth we didn't include QuestionText on submit,
this is done by assigning it on Label, and no need to persist
QuestionText on Hidden
*@
<br />
@Html.TextArea("Answers[" + i + "].AnswerText", answer.AnswerText)
<hr />
++i;
}
<input type="submit" value="Done" />
}
查看主页/ SubmitAnswers
@model SoQna.ViewModels.QnaViewModel
@{
ViewBag.Title = "SubmitAnswers";
}
<h2>SubmitAnswers</h2>
@foreach (var item in Model.Answers)
{
@: Answer to question: @item.QuestionText
<br />
@item.AnswerText
<hr />
}
答案 3 :(得分:0)
我建议建立隐藏字段,如下所示:
<input type="hidden" name="questionsAndAnswers"
value="[{'id':questionId, 'question':questionName, 'answer':answerName},
{'id':questionId, 'question':questionName, 'answer':answerName}...] />
然后序列化发布的隐藏值