[英]ASP.NET - MVC Sending and receiving model from controller to view and back to controller
我想将从数据库获取的数据发送到视图,然后从视图接收数据以将其插入数据库。 我的问题是使用同一模型的 2 个实例。
基本上,我想向用户展示 10 个他可以选择回答的随机问题,然后我想将问题的服务器 id 和他选择的答案发送回。
控制器:
public ActionResult Index()
{
var questions = db.Questions.Where(p => p.subject == "Subject").ToList();
var sessionQuestions = questions.OrderBy(item => rand.Next()).Take(10);
myModel model = new myModel
{
Questions = questions,
randomSample = sessionQuestions,
submitedAnswers = new Dictionary<int, string>();
};
return View(model);
}
[HttpPost]
public ActionResult Index(myModel m)
{
ViewBag["Sample"] = m.submitedAnswers;
return RedirectToAction("Debug");
}
看法:
@model OnlineQuiz.Models.myModel
@using (Html.BeginForm()) {
var i = 1;
foreach (var item in Model.randomSample)
{
var possibleAnswers = @item.possibleAnswers.Split(',');
<div class="question" style="display: block" id=@item.Id runat="server">
<h4>@i. @item.question</h4>
<ul runat="server">
@foreach (var answer in possibleAnswers)
{
<li class="btn btn-primary" style="display: block; margin-bottom:5px" runat="server">@answer</li>
}
</ul>
</div>
i++;
}
<input type="button" id="submit" value="Submit" />
}
如果可以在数组中检索带有问题 id 的提交答案,然后再映射到任何模型,我建议对控制器和视图进行一些更改,例如:
看法:
@model OnlineQuiz.Models.myModel
@using (Html.BeginForm())
{
var i = 1;
foreach (var item in Model.randomSample)
{
var possibleAnswers = @item.possibleAnswers.Split(',');
<div class="question" style="display: block" id="@item.Id">
<h4>@i. @item.question</h4>
<ul">
@foreach (var answer in possibleAnswers)
{
<li class="" style="display: block; margin-bottom:5px" >
<input type="checkbox" id="@item.Id _@answer" name="QuestionAnswer" value="@item.Id _@answer" /> @answer
</li>
}
</ul>
</div>
i++;
}
<input type="submit" id="submit" value="Submit" />
}
并在控制器中
[HttpPost]
public ActionResult Index(string[] QuestionAnswer)
{
// each QuestionAnswer contains only checked value in questionid_answer format
// like :
// 1_ansone
// 1_ansone
// 2_anstwo
// 3_ansthree
foreach(var item in QuestionAnswer){
int id = Convert.ToInt32(item.Split('_')[0].Trim());
string answer = item.Split('_')[1].Trim();
// do save to database or map to model logic here
}
return RedirectToAction("Debug");
}
我希望这会有所帮助。
我们需要在这里实现的是发送一个视图模型,其中包含我们的问题的结构和视图的可能答案。 用户提供答案并将响应发送回服务器。
在我的设计中,我使用 JavaScript 来处理页面和 Ajax 上的逻辑,以便将响应提交回服务器。
我使用 .net core 3.1 和 Microsoft Visual Studio Professional 2019 版本 16.4.2 创建了我的示例
在 JavaScript 中 - 每个答案都映射到一个对象中:
var answerObj = {
id,
value
};
answerObj
包含问题 ID 和答案值。
视图模型将具有以下结构:
public class QuestionStructure
{
public int Id { get; set; }
public string Question { get; set; }
public string PossibleAnswear { get; set; }
}
public class ViewModel
{
public List<QuestionStructure> Questions { get; set; }
public ViewModel()
{
QuestionStructure q1 = new QuestionStructure
{
Id = 1,
Question = "How many days in a leap year?",
PossibleAnswear = "2356,366,212,365"
};
QuestionStructure q2 = new QuestionStructure
{
Id = 2,
Question = "What is the next number in the series 2, 3, 5, 7, 11...?",
PossibleAnswear = "15,88,99,13"
};
QuestionStructure q3 = new QuestionStructure
{
Id = 3,
Question = "How many wheel has a bike got?",
PossibleAnswear = "5,3,4,2"
};
QuestionStructure q4 = new QuestionStructure
{
Id = 4,
Question = "How many fingers have you got?",
PossibleAnswear = "5,8,20,10"
};
List<QuestionStructure> items = new List<QuestionStructure>();
items.Add(q1);
items.Add(q2);
items.Add(q3);
items.Add(q4);
this.Questions = items;
}
}
我们的控制器看起来像这样,我们从 Index 方法向视图发送数据:
private ViewModel viewModel = new ViewModel();
public IActionResult Index()
{
return this.View(viewModel);
}
[Route("/homeController/returnedAnswers")]
public List<ReturnedAnswers> Answers(string json)
{
List<ReturnedAnswers> returnedAnswers = Newtonsoft.Json.JsonConvert.DeserializeObject<List<ReturnedAnswers>>(json);
// here you can do all the logic to manipulate your result...
// We just sent back to the ajax call the json data and we can check it in the console log
return returnedAnswers;
}
cshtml 页面会收到一个 ViewModel 类型的模型,请注意我已经在 HTML 头部注入了 jQuery 作为 CDN:
@model ViewModel;
@{
ViewData["Title"] = "Home Page";
}
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
</head>
@using (Html.BeginForm())
{
foreach (var item in Model.Questions)
{
var question = @item.Question;
var possibleAnswers = @item.PossibleAnswear.Split(',');
<div class="question" style="display: block">
<div class="row">
<div class="col-5">
<label style="margin-right: 1rem">@question</label>
</div>
<div class="col-6">
<select class="mySelect">
<option value="">Select a question</option>
@foreach (var answear in possibleAnswers)
{
<option value="@item.Id">@answear</option>
}
</select>
</div>
</div>
</div>
}
<input type="button" id="submit" value="Submit" />
}
这里要注意的最重要的事情是我们设置下拉选项的 for each 循环。 每个选项都将具有问题 ID 的值,文本将是可能的答案。
这种设计将允许我们稍后将映射对象创建到 JavaScript 中。
我已将 JavaScript 放入不同的文件中 - 但它可以直接嵌入到页面中。
$(document).ready(function () {
var answers = [];
//on change event for all our dropdown
$(".mySelect").change(function () {
var id = $(this).children(':selected').attr('value');
var value = $(this).children(':selected').text();
var answerObj = {
id,
value
};
// check if we are changing an already given answer.
var alreadyIn = answers.find(item => item.id === id);
//if so remove it from mapped array
if (alreadyIn) {
answers = answers.filter(item => item.id !== alreadyIn.id);
}
//map selected answer to our array of objects
answerObj.id = id;
answerObj.value = value;
answers.push(answerObj);
});
// When the submit button is clicked send the request back to the server.
// JSON.stringify(answers) will serialise our array of answers - into a Json format.
$('#submit').on('click', function () {
$.post({
url: '/homeController/returnedAnswers',
dataType: 'json',
data: { "json": JSON.stringify(answers) },
success: function (data) {
console.log(data);
}
});
});
});
js在这里做的很简单。
每次用户从下拉列表中选择一个值时,我们都会将该值和文本映射到我们的对象中:
var answerObj = {
id,
value
};
然后我们将它存储到一个数组中。
answerObj.id = id;
answerObj.value = value;
answers.push(answerObj);
这将是问题 ID 和给定答案的答案映射。
现在我们有了数据结构——我们需要做的就是将它发送回服务器。
$('#submit').on('click', function () {
$.post({
url: '/homeController/returnedAnswers',
dataType: 'json',
data: { "json": JSON.stringify(answers) },
success: function (data) {
console.log(data);
}
});
});
我已将一个事件附加到提交按钮,该事件将触发对我的路由(url)的 Ajax post 调用。
在我们的控制器中,我已将路由定义为以下方法:
[Route("/homeController/returnedAnswers")]
public List<ReturnedAnswers> Answers(string json)
{
List<ReturnedAnswers> returnedAnswers = Newtonsoft.Json.JsonConvert.DeserializeObject<List<ReturnedAnswers>>(json);
// here you can do all the logic to manipulate your result...
// We just sent back to the ajax call the json data and we can check it in the console log
return returnedAnswers;
}
该方法将接收一个与以下类具有相同结构的字符串参数:
public class ReturnedAnswers
{
public string id { get; set; }
public string value { get; set; }
}
由于结果将是一个对象数组 - DeserializeObject 将需要使用List<ReturnedAnswers>
出于示例的目的,我会将数据发送回客户端并将其显示到 console.log 中
您在控制台(右侧)中看到的数组是单击提交后来自服务器的响应。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.