【问题标题】:Issue With Radio Buttons ASP.Net Core Razor Pages单选按钮问题 ASP.Net Core Razor 页面
【发布时间】:2020-12-10 06:49:58
【问题描述】:

我目前在尝试使用剃须刀页面和 ASP.net Core 通过单选按钮从多项选择答案选项中发​​布信息时遇到问题。 我找到了一些有关 MVC 的信息,但无法完全解决我的问题。

我有一个显示问题列表的 Razor 页面,并且在每个问题中都有可能的答案选项。 这是我下面的表格:

<form method="post">
    @for (int i = 0; i < Model.Questions.Count(); i++)
    {
        <h4>@Model.Questions.ElementAt(i).QuestionBody</h4>
        <input type="hidden" asp-for="Question.QuestionBody" />

        @foreach (var answer in Model.Answers)
        {
            var groupID = "question" + i;

            <div class="input-group">
                <div class="input-group-prepend">
                    <div class="input-group-text">
                        <input type="radio" name="@groupID" />
                        <label>answer.AnswerBody</label>
                    </div>
                </div>
            </div>
        }
    }
    <button type="submit" class="btn btn-primary">Save</button>
</form>

根据我阅读的信息,我认为我需要删除 name 属性,但目前它是我对正确问题的答案分组并允许我每页选择多个答案的原因。

包含表单的 ApTest razor 页面的页面模型是

public class ApTestModel : PageModel
    {
        private readonly IConfiguration config;
        public IApTestData ApTestData { get; set; }

        [BindProperty]
        public IEnumerable<Question> Questions { get; set; }
        [BindProperty]
        public Question Question { get; set; }
        public int QuestionID { get; set; }
        [BindProperty]
        public List<Answer> Answers { get; set; }
        [BindProperty]
        public Answer Answer { get; set; }
        [BindProperty]
        public TestAttempt TestAttempt { get; set; }


        public ApTestModel(IConfiguration config, IApTestData ApTestData)
        {
            this.config = config;
            this.ApTestData = ApTestData;
        }

        public void OnGet()
        {
            Questions = ApTestData.GetQuestionsAndAnswers(QuestionID);

        }

        public void OnPost()
        {
            AppUser appUser = new AppUser
            {
                Email = User.Identity.Name,
            };

            ApTestData.SaveApTestAttempt(Answers, appUser);
        }
    }
}

SaveApTestAttempt 方法在这里:

public void SaveApTestAttempt(List<Answer> answers, AppUser appUser)
        {
            var tempAppUser = db.Users.SingleOrDefault(user => user.Email == appUser.Email);
            foreach (var answer in answers)
            {
                TestAttempt testAttempt = new TestAttempt
                {
                    SelctedAnswer = answer,
                    Applicant = appUser,
                    ApplicantID = tempAppUser.Id
                };

                db.TestAttempts.Add(testAttempt);
            }
        }

所涉及的实体是 Question、Answer 和 TestAttempt(所有单独的类,但在此处合并以便于查看):

 public class Question
    {
        public int ID { get; set; }
        public string QuestionBody { get; set; }
        public List<Answer> Answers { get; set; }
        public QuestionTypeID QuestionTypeID { get; set; }
        public QuestionType QuestionType { get; set; }

        public Question()
        {
            Answers = new List<Answer>();
        }
    }

public class Answer
    {
        public int ID { get; set; }
        public string AnswerBody { get; set; }
        public bool IsCorrect { get; set; }
        public Question Question { get; set; }
        public int QuestionID { get; set; }
    }

public class TestAttempt
    {
        [Key]
        public int ID { get; set; }
        public AppUser Applicant { get; set; }
        public string ApplicantID { get; set; }
        public Answer SelctedAnswer { get; set; }
        public int AnswerID { get; set; }


    }

我知道我应该在我的表单中绑定和使用 asp-for,但我已经尝试过,以及删除 name 属性并添加一个值,但我认为我没有添加正确的东西。 我使用的是 Model.Questions.ElementAt(i).Answers[j].AnswerID

对于 ASP.Net Core 世界来说还是相当新的,并且正在为我的 uni 论文项目工作, 任何帮助将不胜感激!

【问题讨论】:

    标签: c# asp.net asp.net-core razor radio-button


    【解决方案1】:

    模型绑定在源代码中查找名称模式 prefix.property_name。如果没有找到,它只查找不带前缀的 property_name。由于名称与属性名称不匹配,您为 @groupID 定义的内容无法绑定到模型。

    您的代码还有一个错误是您没有在处理程序中定义Answers,而是在剃须刀页面中循环它,这是不可能的。

    public class ApTestModel : PageModel
    {
        private readonly IConfiguration config;
    
        [BindProperty]
        public IEnumerable<Question> Questions { get; set; }
        [BindProperty]
        public Question Question { get; set; }
        public int QuestionID { get; set; }
        [BindProperty]
        public List<Answer> Answers { get; set; }
        [BindProperty]
        public Answer Answer { get; set; }
        [BindProperty]
        public TestAttempt TestAttempt { get; set; }
    
    
        public PrivacyModel(IConfiguration config)
        {
            this.config = config;
        }
    
        public void OnGet()
        {
            Questions = new List<Question>()
            {
                new Question(){
                    ID=1,
                    QuestionBody="question1"                    
                },
                new Question(){
                    ID=2,
                    QuestionBody="question2"
                },
                new Question(){
                    ID=3,
                    QuestionBody="question3"
                }
            };
            Answers = new List<Answer>(){
                        new Answer() {ID=1, AnswerBody="an1", QuestionID=1} ,
                        new Answer() {ID=2, AnswerBody="an2", QuestionID=1} ,
                        new Answer() {ID=3, AnswerBody="an3", QuestionID=1} 
                    };
        }
    
        public void OnPost()
        {
            AppUser appUser = new AppUser
            {
                Email = "aaaa",
            };
    
            SaveApTestAttempt(Answers, appUser);
        }
        public void SaveApTestAttempt(List<Answer> answers, AppUser appUser)
        {
            //...
        }
    }
    

    更改您的剃须刀页面,如下所示(不确定要绑定到单选按钮的 Answer 类中的哪个值。您可以自己更改名称):

    <form method="post">
        @for (int i = 0; i < Model.Questions.Count(); i++)
        {
            <h4>@Model.Questions.ElementAt(i).QuestionBody</h4>
            <input type="hidden" name="[@i].QuestionBody" asp-for="@Model.Questions.ElementAt(i).QuestionBody" />
    
            @foreach (var answer in Model.Answers)
            {
                var groupID = "[" + i + "].AnswerBody";
                <input type="hidden" asp-for="@answer.ID" />
                <div class="input-group">
                    <div class="input-group-prepend">
                        <div class="input-group-text">
                         <input type="radio" name="@groupID" value="@answer.AnswerBody" />
                            <label>@answer.AnswerBody</label>
                        </div>
                    </div>
                </div>
            }
        }
        <button type="submit" class="btn btn-primary">Save</button>
    </form>
    

    结果:

    【讨论】:

    • 谢谢@Rena,这太棒了。我的答案包含在我使用 Linq 的 Get Questions 方法中。Include 所以我知道他们会在那里收到。答案仍然显示为空,因此必须将 foreach 更改为 @foreach (var answer in Model.Questions.ElementAt(i).Answers)
    猜你喜欢
    • 1970-01-01
    • 2020-06-03
    • 1970-01-01
    • 2018-05-07
    • 1970-01-01
    • 2020-04-09
    • 1970-01-01
    • 2015-03-31
    • 2021-12-17
    相关资源
    最近更新 更多