繁体   English   中英

ASP.NET - MVC 从控制器发送和接收模型到视图并返回控制器

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM