You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无法获取单选按钮选中值,在线投票系统数据接收问题求助

问题分析与修复方案

嘿,我仔细看了你的代码,发现几个关键问题导致你拿不到单选按钮的选中值,而且投票数据也没法正确写入数据库。咱们一步步来修复:

1. Get Vote方法的查询逻辑错误

你在Get方法里查询Question的条件写错了,这会导致你永远拿不到对应ID的问题:

// 错误代码
var Question = await poolDbContext.Questions.Include(A => A.Answers).AsNoTracking().SingleOrDefaultAsync(r => r.Id == r.Id);

r.Id == r.Id永远为true,会返回数据库里第一个Question(甚至抛出异常),完全没用到传入的id参数。改成下面这样:

// 修复后
var Question = await poolDbContext.Questions.Include(A => A.Answers).AsNoTracking().SingleOrDefaultAsync(r => r.Id == id);

2. 视图的提交按钮位置错误

你的Vote.cshtml把提交按钮放在了foreach循环内部,这会导致每个选项下面都有一个提交按钮,还可能干扰单选按钮的分组逻辑。把按钮移到循环外面:

@model PoolManager.Models.Question
<div>
    @Html.HiddenFor(x => x.Id)
    <h3>@Model.Text</h3>
    @foreach (var a in Model.Answers)
    {
        <p>
            @Html.RadioButtonFor(b => b.SelectedAnswer, a.Id)
            @a.Text
        </p>
    }
    <input type="submit" /> <!-- 移到循环外部,一个按钮就够 -->
</div>

另外你循环里的@Model.SelectedAnswer是调试用的,上线前可以删掉。

3. Post方法未实际保存投票数据

你的VotePost方法只是调用了SaveChanges(),但根本没创建Vote对象、关联选中的答案,等于啥都没存。修改成下面这样:

[HttpPost, ActionName("Vote")]
[ValidateAntiForgeryToken]
public ActionResult VotePost(Question question)
{
    try
    {
        if (ModelState.IsValid)
        {
            using (var poolDbContext = new PoolContext())
            {
                // 先验证选中的答案是否属于当前问题,防止恶意提交
                var selectedAnswer = poolDbContext.Answers.FirstOrDefault(a => a.Id == int.Parse(question.SelectedAnswer) && a.QuestionId == question.Id);
                if (selectedAnswer == null)
                {
                    ModelState.AddModelError("", "无效的投票选项");
                    return View(question);
                }

                // 创建投票记录
                var vote = new Vote
                {
                    IpAdress = HttpContext.Connection.RemoteIpAddress.ToString(),
                    VoteDate = DateTime.Now,
                    AnswerId = selectedAnswer.Id // 关联选中的答案
                };

                poolDbContext.Votes.Add(vote);
                poolDbContext.SaveChanges(); // 现在才真正保存数据

                return RedirectToAction("Index");
            }
        }
        return View(question);
    }
    catch (DbUpdateException)
    {
        ModelState.AddModelError("", "Unable to save changes. Try again, and if the problem persists see your system administrator.");
    }
    return View(question);
}

4. Vote模型的关系逻辑错误

当前你的Vote模型里有List<Question> Questions,这不符合业务逻辑——一个投票应该对应一个答案,而不是多个问题。修改Vote模型:

public class Vote
{
    public int Id { get; set; }
    public string IpAdress { get; set; }
    public DateTime VoteDate { get; set; }
    // 移除多余的List<Question>,添加Answer关联
    public int AnswerId { get; set; }
    public virtual Answer Answer { get; set; }

    public Vote()
    {
        // 无需初始化Questions
    }
}

记得在你的DbContext里配置好Vote和Answer的外键关系(比如在OnModelCreating方法里)。

5. Question模型的SelectedAnswer类型优化

当前SelectedAnswer是string类型,但你绑定的是a.Id(int),虽然模型绑定能自动转换,但改成int类型更直观,避免转换错误:

public class Question
{
    // ... 其他属性
    public int SelectedAnswer { get; set; } // 从string改为int
}

对应的视图代码不用改,因为a.Id本来就是int,类型匹配后模型绑定会更顺畅。

测试建议

做完这些修改后,你可以:

  • 先测试Get Vote方法,确认能正确加载对应问题的所有选项
  • 选择一个选项提交,检查Post方法中question.SelectedAnswer是否拿到了正确的答案ID
  • 查看数据库,确认Vote表中新增了投票记录,且AnswerId关联正确

内容的提问来源于stack exchange,提问作者Dorin Munreanu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 09:41:36