【问题标题】:Maintain Checked Radio Group after Post发布后维护检查的无线电组
【发布时间】:2014-06-30 19:09:33
【问题描述】:

我怎样才能不仅维护广播组的问题和答案,而且在返回错误的帖子之后维护已检查的广播?

“联系”页面返回多项选择题列表。如果出现错误,则视图不包含答案或所选值。

我已经四处搜索,但没有找到一个可以将所有内容组合在一起的答案。这个很接近:How do I transfer ViewModel data between POST requests in ASP.NET MVC?

但我不敢相信四年后没有更简单的解决方案。

肯说:

您可以从中获取当前选定的项目(即验证失败) 包含已发布并绑定到的 id 的属性 你的类的实例。

...这就是我本质上想要做的:坚持检查过的收音机。但我不得不认为有一种方法可以做到这一点,无需绑定类或设置隐藏值。

这是我目前所拥有的:

public ActionResult Contact()
    {
        SomeViewModel vm = new SomeViewModel();
        vm.Questions = workflow.GetQuestions().ToList();
        vm.Answers = workflow.GetPossibleAnswers();
        return View(vm);//populated radio group
    }

[HttpPost]
public ActionResult SendForm(FormCollection form)
    {
        if (String.IsNullOrEmpty(form["FullName"]))
        {
            ModelState.AddModelError("FullName", "Must enter a name,");

            SomeViewModel vm = new SomeViewModel();
            vm.Questions = workflow.GetQuestions().ToList();
            vm.Answers = workflow.GetPossibleAnswers();
            List<SelectedAnswer> selectedAnswers = ParseSelectedAnswers(form);
            vm.PreviousAnswers = selectedAnswers;
            return View(vm);//returns without the previously selected radios
        }
    //more code…
    }

public class SomeViewModel : RegisterExternalLoginModel
{
    public List<Question> Questions { get; set; }
    public IList<Answer> PossibleAnswers { get; set; }
    public List<SelectedAnswer> SelectedAnswers { get; set; }
    public IList<SelectedAnswer> PreviousAnswers 
    { 
        set 
        { 
            foreach(Question q in Questions)
            {
                q.SelectedAnswers = value.Where(t => t.questionId == q.objectId).ToList() ;
            }
        } 
    }
}

解析方法

private  List<SelectedAnswer> ParseSelectedAnswers(FormCollection form)
        {
            List<SelectedAnswer> selectedAnswers = new List<SelectedAnswer>();
            var questionElements = form.AllKeys.Where(t => t.StartsWith("Questions["));
            var uniqueQuestionElements = questionElements.Select(t=> t.Substring(0, t.IndexOf(']') +1)).Distinct();
            var count = uniqueQuestionElements.Count();

            foreach(var element in uniqueQuestionElements)
            {
                long x = ParseElementToLong(form, element, "ObjectId");
                long y = ParseElementToLong(form, element, "SelectedAnswer");

                selectedAnswers.Add(new SelectedAnswer() { questionId = x, answerId = y });            
            }
            return selectedAnswers;
        }

所以,问题是视图在 ModelError 之后返回,没有任何问题、答案或检查过的无线电。

我正在使用带有 Razor 的 MVC 5。

【问题讨论】:

    标签: c# asp.net asp.net-mvc http-post radio-group


    【解决方案1】:

    因为您没有将 ViewModel 发回,所以请使用您发送到视图并从视图接收的相同视图模型。

    [HttpPost]
    public ActionResult SendForm(FormCollection form)
    {
        if (String.IsNullOrEmpty(form["FullName"]))
        {
            ModelState.AddModelError("FullName", "Must enter a name,");
            return View(form);
        }
    //more code…
    }
    

    如果我对你完全诚实,我讨厌我在这里看到的一切......

    • FormCollection 到底是什么?
    • 您为什么不专门为您的表单创建视图模型?
    • 为什么要在 Controller Action 中验证表单值?

      您可以使用诸如 [Required] 之类的注释来执行您已经手动执行的验证。

    【讨论】:

    • 这会引发一个错误,表明它正在期待一个视图模型,但收到了一个表单。 FormCollection 是表单的转储(一串字符串)。表单非常复杂,并且经常更新,因此直接获取表单并将其传递给各种工作流程(它们都有一个序列化方法)更方便,而不是不断更新视图模型。一般来说,我更喜欢 viewmodel 帖子,但在这种情况下,表单集合是一个糟糕的解决方案,效果很好。
    • 不行,你的问题就是一个例子,真的要那么费力去改吗?您唯一的其他选择是重建视图模型及其值并按照我向您展示的方式返回它。
    【解决方案2】:

    这会起作用。

    public ActionResult Contact()
    {
        SomeViewModel vm = new SomeViewModel();
        vm.Questions = workflow.GetQuestions().ToList();
        vm.Answers = workflow.GetPossibleAnswers();
        return View(vm);//populated radio group
    }
    
    [HttpPost]
    public ActionResult SendForm(FormCollection form)
    {
        if (String.IsNullOrEmpty(form["FullName"]))
        {
            ModelState.AddModelError("FullName", "Must enter a name,");
    
            SomeViewModel vm = new SomeViewModel();
            vm.Questions = workflow.GetQuestions().ToList();
            vm.Answers = workflow.GetPossibleAnswers();
            return View(vm);//populated radio group
        }
    //more code…
    }
    
    public class SomeViewModel : RegisterExternalLoginModel
    {
    public List<Question> Questions { get; set; }
    public IList<Answer> PossibleAnswers { get; set; }
    public List<SelectedAnswer> SelectedAnswers { get; set; }
    public IList<SelectedAnswer> PreviousAnswers 
    { 
        set 
        { 
            foreach(Question q in Questions)
            {
                q.SelectedAnswers = value.Where(t => t.questionId == q.objectId).ToList() ;
            }
        } 
    }
    }
    

    【讨论】:

    • 这是一半。另一半是维护选定的答案。我添加了一个解析方法,但它仍然无法正常工作。请参阅上面的编辑。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-11-14
    • 2012-05-29
    • 2012-05-29
    • 2021-09-23
    • 2013-08-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多