首页 > 解决方案 > 为什么我的列表没有在帖子之间的 PageModel 上保持状态?

问题描述

我在我的 PageModel 上维护一个列表作为BindProperty.

当用户在页面上提交表单时,应添加此列表,并重置获取其值的输入。

<form class="ratingQuestionForm" method="post" asp-page-handler="AddQuestion">
    <input type="hidden" name="questionType" id="questionType" value="Rating" />
    <textarea name="questionText" id="questionText" class="form-control mb-1"
        required></textarea>
</form>
<a class="btn btn-outline-dark add-rating-question">Add Rating
    Question</a>

<script>
    $(".add-rating-question").on("click", function () {
        $(".ratingQuestionForm").submit();
        $(this).closest("textarea").val("");
    });
</script>

在后端,我使用TempData["Questions"]这种方式提交的问题列表作为短期存储。

[BindProperties]
public class CreateModel : PageModel
{
    public List<Question> Questions { get; set; }

    // The usual constructor and DI stuff has been removed for brevity.
    public async Task OnGetAsync()
    {
        // If there are already questions in ViewData, load them.
        if (ViewData["Questions"] is not null)
        {
            this.Questions = ViewData["Questions"] as List<Question>;
        }

        // Basically everything not related to the question removed for brevity.
    }

    public void OnPostAddQuestion(string type, string text)
    {
        var _type = type switch
        {
            "Rating" => QuestionType.Rating,
            _ => QuestionType.OpenEnded
        };

        // Load existing questions if there are any.
        if (ViewData["Questions"] is not null)
        {
            this.Questions = ViewData["Questions"] as List<Question>;
        }

        this.Questions.Add(new Question
        {
            Type = _type,
            QuestionText = text
        }
    }
}

当我在 UI 上没有看到我想要的行为时,我让页面为我构建了一个问题列表。这表明只有最后一个添加的问题持续存在于模型中。

@if (Model.Questions is not null && Model.Questions.Any())
{
    <ul class="list-group list-group-flush">
        @foreach (var q in Model.Questions)
        {
            <li class="list-group-item">@q.QuestionText</li>
        }
    </ul>
}

如何通过帖子坚持我的问​​题?

标签: c#asp.net-corerazor-pages

解决方案


在您的问题中,我看到您说“TempData”,但在您的代码中,我看到您使用的是“ViewData”。我相信 ViewData 仅适用于当前请求。您将要使用的是 TempData。但是请注意,TempData 字典不能保存复杂的对象。为了解决这个问题,您可以序列化和反序列化您需要存储的任何内容。我建议使用 JavaScript Object Notation (JSON)。您可以使用本文中讨论的 System.Text.Json 命名空间/库进行序列化:

https://docs.microsoft.com/en-us/dotnet/standard/serialization/system-text-json-overview?pivots=dotnet-core-3-1

这是我使用自己的代码尝试解决您的问题的方法:

using Microsoft.AspNetCore.Mvc.RazorPages;
using System.Collections.Generic;
using System.Text.Json;

namespace StackOverflowQA.Pages
{
    public class CreateModelModel : PageModel
    {
        public class Question
        {
            public string Type { get; set; }
            public string Text { get; set; }
        }

        private const string questionsKey = "Questions";

        public List<Question> Questions { get; set; }

        public void OnGet()
        {
            Questions = GetQuestions();
        }

        public void OnPostAddQuestion(string type, string text)
        {
            Questions = GetQuestions();
            Questions.Add(new Question { Type = type, Text = text });
            TempData[questionsKey] = JsonSerializer.Serialize(Questions);
        }

        private List<Question> GetQuestions()
        {
            TempData.TryGetValue(questionsKey, out object o);
            if (o is null)
                return new List<Question>();
            return JsonSerializer.Deserialize<List<Question>>((string)o);
        }
    }
}

这是另一篇文章,解释了 TempData 的工作原理: https ://www.learnrazorpages.com/razor-pages/tempdata


推荐阅读