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

时间:2020-01-25 12:26:08

标签: c# asp.net asp.net-mvc asp.net-mvc-5

我想将从数据库中获取的数据发送到视图,然后再从视图接收数据以将其插入数据库。 我的问题是使用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" />
 }

2 个答案:

答案 0 :(得分:0)

如果可以用数组中的问题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");
}

我希望这会有所帮助。

答案 1 :(得分:0)

我们在这里需要实现的是发送一个视图模型,该模型包含用于我们的问题和对视图的可能答案的结构。用户提供答案并将响应发送回服务器。

在我的设计中,我使用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类型的模型,请注意,我已经将jQuery作为CDN注入到HTML头中:

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

最重要的是在其中设置下拉选项的每个循环中。每个选项都将具有问题ID的值,文本将为possibleAnswer。

这种设计将使我们以后可以将映射对象创建到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);
        }
    });
});

我已经在提交按钮上附加了一个事件,该事件将触发对我的route(url)的Ajax发布调用。

在我们的控制器中,我定义了以下方法的路由:

[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

在这里您可以看到结果: enter image description here

您在控制台(右侧)中看到的数组是单击提交后服务器的响应。

相关问题