简体   繁体   English

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

[英]ASP.NET - MVC Sending and receiving model from controller to view and back to controller

I want to send data fetched from database to the view, and then receive data back from the view to insert it into the database.我想将从数据库获取的数据发送到视图,然后从视图接收数据以将其插入数据库。 My problem is working with 2 instances of the same model.我的问题是使用同一模型的 2 个实例。

Basically i want to show the user 10 random questions which he can answer with selection, and then I want to send back to the server id of the question and the answer he selected.基本上,我想向用户展示 10 个他可以选择回答的随机问题,然后我想将问题的服务器 id 和他选择的答案发送回。

Controller:控制器:

    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");
    }

View:看法:

@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" />
 }

If it's fine to retrieve submitted answer with question id in array and later mapping to any model, I would suggest to make some changes on controller and views like as:如果可以在数组中检索带有问题 id 的提交答案,然后再映射到任何模型,我建议对控制器和视图进行一些更改,例如:

View:看法:

@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" />
}

and in Controller并在控制器中

[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");
}

I hope this will help somehow.我希望这会有所帮助。

What we need to achieve here is sending a view model that contains a structure for our questions and possible answers to a view.我们需要在这里实现的是发送一个视图模型,其中包含我们的问题的结构和视图的可能答案。 The user provides the answers and send the response back to the server.用户提供答案并将响应发送回服务器。

In my design I have used JavaScript to handle the logic on the page and Ajax in order to submit the response back to the server.在我的设计中,我使用 JavaScript 来处理页面和 Ajax 上的逻辑,以便将响应提交回服务器。

I have created my example using .net core 3.1 and Microsoft Visual Studio Professional 2019 Version 16.4.2我使用 .net core 3.1 和 Microsoft Visual Studio Professional 2019 版本 16.4.2 创建了我的示例

In the JavaScript - each answer is mapped into an object :在 JavaScript 中 - 每个答案都映射到一个对象中:

    var answerObj = {
        id,
        value
    };

The answerObj contains the question id and the answer value. answerObj包含问题 ID 和答案值。

The view model will have the following structure:视图模型将具有以下结构:

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;
    }
}

Our controller will look like this and we send data to the view from the Index method:我们的控制器看起来像这样,我们从 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;
    }

The cshtml page will receive a model of type ViewModel, please note that I have injected jQuery as a CDN in the HTML head: 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" />
}

The most important thing to note here is the for each loop where we set the drop down options.这里要注意的最重要的事情是我们设置下拉选项的 for each 循环。 Each options will have the value of the question id and the text will be the possibleAnswer.每个选项都将具有问题 ID 的值,文本将是可能的答案。

This design will allow us to later create our mapping object into JavaScript.这种设计将允许我们稍后将映射对象创建到 JavaScript 中。

I have put the JavaScript into a different file - but it can be embedded directly into the page.我已将 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);
            }
        });
    });
});

What the js is doing here is quite simple. js在这里做的很简单。

Each time the user select a value from the dropdown we map the value and the text into our object:每次用户从下拉列表中选择一个值时,我们都会将该值和文本映射到我们的对象中:

var answerObj = {
    id,
    value
};

We then store it into an array.然后我们将它存储到一个数组中。

    answerObj.id = id;
    answerObj.value = value;
    answers.push(answerObj);

That would be the answers mapping of questions ids and given answers.这将是问题 ID 和给定答案的答案映射。

Now we have the data structure - all we need to do is sending it back to the server.现在我们有了数据结构——我们需要做的就是将它发送回服务器。

$('#submit').on('click', function () {
    $.post({
        url: '/homeController/returnedAnswers',
        dataType: 'json',
        data: { "json": JSON.stringify(answers) },
        success: function (data) {
            console.log(data);
        }
    });
});

I have attached an event to the submit button which will trigger an Ajax post call to my route(url).我已将一个事件附加到提交按钮,该事件将触发对我的路由(url)的 Ajax post 调用。

In our controller I have defined my routing to the following method:在我们的控制器中,我已将路由定义为以下方法:

[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;
}

The method will receive a string parameter which will have the same structure as the following class:该方法将接收一个与以下类具有相同结构的字符串参数:

public class ReturnedAnswers
{
    public string id { get; set; }
    public string value { get; set; }
}

As the result will be an array of objects - DeserializeObject will need to use a List<ReturnedAnswers>由于结果将是一个对象数组 - DeserializeObject 将需要使用List<ReturnedAnswers>

For the purpose of the example I will be sending the data back to the client and display it into the console.log出于示例的目的,我会将数据发送回客户端并将其显示到 console.log 中

Here you can see the result:在这里你可以看到结果: 在此处输入图片说明

The array you see in the console(right hand side) is the response from the server after clicking submit.您在控制台(右侧)中看到的数组是单击提交后来自服务器的响应。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 从控制器发送整数值以在ASP.NET MVC中查看 - sending integer value from controller to view in asp.net mvc ASP.Net MVC 将表数据从视图发送到 controller - ASP.Net MVC Sending Table data from view to controller ASP.NET 核心 MVC - 将 Model 数据从视图传递回 Controller - ASP.NET Core MVC - Passing Model Data Back to Controller from View 在ASP.NET MVC中从View传递模型到Controller - Passing Model to Controller from View in ASP.NET MVC c# asp.net core mvc 将数据从视图传递到控制器并从控制器返回到视图 - c# asp.net core mvc passing data from view to controller and from controller back to view ASP.net MVC2。 填充的模型没有回到控制器 - ASP.net MVC2. Populated model is not getting back to the controller 将模型发布回ASP.NET MVC3中的控制器 - Posting a model back to controller in ASP.NET MVC3 MVC ASP.NET提交给Controller时在View中获取ViewData.Model - MVC ASP.NET Getting back my ViewData.Model in my View when I submit to a Controller How can you maintain model state in ASP.NET Core between repeatedly displaying the Model in a View and sending the model back to the Controller? - How can you maintain model state in ASP.NET Core between repeatedly displaying the Model in a View and sending the model back to the Controller? 视图未将模型传递给控制器​​-ASP.Net MVC - View is not passing the model to controller - ASP.Net MVC
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM