用剃须刀绑定ASP.NET MVC页面中的单选按钮

ggazkfy8  于 2023-02-14  发布在  .NET
关注(0)|答案(3)|浏览(156)

我有4个单选按钮(考试问题和4个选项可供选择)的网页。与下面的代码,我可以阅读用户点击按钮后的选项值。
我有两个问题:

  • 为什么第一次加载页面时选中了所有单选按钮?
  • 发帖后如何发现选中了哪个单选按钮?

谢谢!
StudentQuestions.cshtml

@page "{examId:int?}"
@model VerityLearn.WebUI.Pages.Questions.StudentQuestionsModel
@{
    ViewData["Title"] = "StudentQuestions";
}
    <div>
        <form method="post">
            @Html.LabelFor(model => model.QuestionViewModel.QuestionText);

                <p>Select the correct option.</p>

                int optionIndex = -1;

                @foreach (OptionViewModel opt in Model.QuestionViewModel.Options)
                {
                    optionIndex++;

                    @Html.RadioButtonFor(model => model.QuestionViewModel.Options[optionIndex], Model.QuestionViewModel.Options[optionIndex]);
                    @opt.OptionText<br />
                }

            <button type="submit" asp-route-questionIndex="@(Model.QuestionNdx + 1)" class="btn btn-primary @nextDisabled">Next</button>

        </form>
    </div>

StudentQuestions.cshtml.cs

public class StudentQuestionsModel : PageModel
    {
        //private readonly VerityContext _context;
        private readonly SignInManager<VerityUser> _signInManager;
        private readonly UserManager<VerityUser> _userManager;
        private readonly IStudentQuesionsUOW _studentQuesionsUOW;
        private readonly VerityLearn.DataAccess.VerityContext _context;

        public StudentQuestionsModel(
            VerityContext context,
            SignInManager<VerityUser> signInManager,
            UserManager<VerityUser> userMrg,
            IStudentQuesionsUOW studentQuesionsUOW
        )
        {
            _context = context;
            _signInManager = signInManager;
            _userManager = userMrg;
            _studentQuesionsUOW = studentQuesionsUOW;
        } // end public StudentQuestionsModel(VerityContext context, SignInManager<VerityUser> signInManager, UserManager<VerityUser> userMrg)

        [BindProperty]
        public QuestionViewModel QuestionViewModel { get; set; }

        [BindProperty]
        public Question Question { get; set; }

        public async Task<IActionResult> OnPostAsync()
        {
            ... Not sure what to do here ...
        }

QuestionViewModel.cs

public class QuestionViewModel
    {
        public int QuestionId { get; set; }

        public int ExamQuestionOrder { get; set; }

        public string QuestionText { get; set; }

        public bool? IsSingleSelection { get; set; }

        public List<OptionViewModel> Options { get; set; }
    }
toe95027

toe950271#

您感兴趣的是所选单选按钮的值。在我的演示中,为了简化起见,我假设它是一个id。假设单选按钮的名称为AnswerSelectedId,则在提交表单时将标记为AnswerSelectedId的值回发到服务器。因此,您需要在模型中定义一个名为AnswerSelectedId的属性,以便模型绑定能够匹配这两个属性。
这里有一个快速的演示来展示你试图实现什么借用大量迈克布林德的答案。
StudentQuestions.cshtml.cs

public class OptionViewModel
{
    public int Id { get; set; }
    public string OptionText { get; set; }
}

public class QuestionViewModel
{
    public int QuestionId { get; set; }
    public int ExamQuestionOrder { get; set; }
    public string QuestionText { get; set; }
    public bool? IsSingleSelection { get; set; }
    public List<OptionViewModel> Options { get; set; }
}

public class StudentQuestionsModelModel : PageModel
{
    public void OnGet()
    {
        QuestionViewModel = new QuestionViewModel
        {
            QuestionId = 1,
            ExamQuestionOrder = 1,
            QuestionText = "Question1",
            IsSingleSelection = false,
            Options = new List<OptionViewModel>()
            {
                new OptionViewModel
                {
                    Id = 1,
                    OptionText = "Option 1"
                },
                new OptionViewModel
                {
                    Id = 2,
                    OptionText = "Option 2"
                }
            }
        };
    }

    [BindProperty]
    public QuestionViewModel QuestionViewModel { get; set; }

    [BindProperty]
    public int AnswerSelectedId { get; set; }   //this is the key bit

    public async Task<IActionResult> OnPostAsync()
    {
        return Content($"The answer selected was {AnswerSelectedId}");
    }
}

StudentQuestions.cshtml

@page "{examId:int?}"
@model StudentQuestions.Pages.StudentQuestionsModel  

<div>
    <form method="post">
        @Html.LabelFor(model => model.QuestionViewModel.QuestionText);

        <p>Select the correct option.</p>    

        @for (var i = 0; i < Model.QuestionViewModel.Options.Count(); i++)
        {
            <input type="radio" asp-for="AnswerSelectedId" 
                   value="@Model.QuestionViewModel.Options[i].Id" /> 
                  @Model.QuestionViewModel.Options[i].OptionText
                  <br>
        }

        <button type="submit" class="btn btn-primary">Next</button>
    </form>
</div>

注意asp-for属性如何匹配页面模型中的属性AnswerSelectedId。
当您按下“提交”按钮时,表单数据将被发送到服务器。如果您使用“发送到服务器的表单数据”下的开发者工具,它将如下所示(取决于所选的值)

AnswerSelectedId: 1

然后,模型绑定会将该值绑定到名为AnswerSelectedId的属性,然后您就可以在onPostAsync方法中访问它。

xmd2e60i

xmd2e60i2#

如果要使用单选按钮来表示互斥选项,则应通过应用相同的name属性值将它们分组在一起:

<input type="radio" name="question1" value="answer1" /> Answer 1
<input type="radio" name="question1" value="answer2" /> Answer 2
<input type="radio" name="question1" value="answer3" /> Answer 3

您正在使用的Html helper为每个单选按钮生成不同的id和name属性值。我会避免在Razor Pages中使用Html helper,而使用标记helper:

@for (var i = 0; i <  Model.QuestionViewModel.Options.Count(); i++)
 {
    <input type="radio" asp-for="QuestionViewModel.QuestionId" value="@Model.QuestionViewModel.Options[i]" /> @Model.QuestionViewModel.Options[i].OptionText<br/>
 }

更多信息:https://www.learnrazorpages.com/razor-pages/forms/radios

ubof19bj

ubof19bj3#

我建议使用**Animated radios & checkboxes (noJS)**,它的动画效果非常好。你可以按照下面的步骤在你的Razor页面中使用它:

中央支助事务厅:

.checkbox label:after, .radio label:after {
    content: '';
    display: table;
    clear: both;
}
 
.checkbox .cr, .radio .cr {
    position: relative;
    display: inline-block;
    border: 1px solid #a9a9a9;
    border-radius: .25em;
    width: 1.3em;
    height: 1.3em;
    float: left;
    margin-right: .5em;
}
 
.radio .cr {
    border-radius: 50%;
}
 
.checkbox .cr .cr-icon, .radio .cr .cr-icon {
    position: absolute;
    font-size: .8em;
    line-height: 0;
    top: 50%;
    left: 20%;
}
 
.radio .cr .cr-icon {
    margin-left: 0.04em;
}
 
.checkbox label input[type="checkbox"], .radio label input[type="radio"] {
    display: none;
}
 
.checkbox label input[type="checkbox"] + .cr > .cr-icon, .radio label input[type="radio"] + .cr > .cr-icon {
    transform: scale(3) rotateZ(-20deg);
    opacity: 0;
    transition: all .3s ease-in;
}
 
.checkbox label input[type="checkbox"]:checked + .cr > .cr-icon, .radio label input[type="radio"]:checked + .cr > .cr-icon {
    transform: scale(1) rotateZ(0deg);
    opacity: 1;
}
 
.checkbox label input[type="checkbox"]:disabled + .cr, .radio label input[type="radio"]:disabled + .cr {
    opacity: .5;
}

控制器:

public async Task<ActionResult> Edit(int id)
{
    //code omitted for brevity
    return PartialView("_Edit", model);
}

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Update([Bind(Exclude = null)] GroupViewModel model, 
    params string[] selectedRoles)
{
    //code omitted for brevity
    await this.GroupManager.UpdateGroupAsync(group);
    selectedRoles = selectedRoles ?? new string[] { };
    await this.GroupManager.SetGroupRolesAsync(group.Id, selectedRoles);
}

视图:

@model Demo.Models.GroupViewModel

<div class="form-group">
    @Html.Label("Roles", new { @class = "col-md-3 control-label" })
    <div class="col-md-6">
 
        <div class="checkbox">
            <label>
                <input type="checkbox" id="checkAll" name="" class="" />
                <span class="cr"><i class="cr-icon glyphicon glyphicon-ok"></i></span>
                <text id= "checkText">Tümü?</text> 
            </label>
        </div>
 
        @foreach (var role in Model.RolesList)
        {
            <div class="checkbox">
                <label>
                    <input type="checkbox" name="selectedRoles" value="@role.Text" checked="@role.Selected" class="" />
                    <span class="cr"><i class="cr-icon glyphicon glyphicon-ok"></i></span>
                    @role.Text
                </label>
            </div>
        }
    </div>
</div>

<script>
    // for selecting All / None
    $("#checkAll").change(function () {
        var checked = $(this).prop("checked");
        $("input:checkbox").prop('checked', checked);
        $('#checkText').text(checked ? 'None?' : 'All?');
    });     
</script>

相关问题