邮寄后维护收听广播组

时间:2014-06-30 02:49:01

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

如何在收到错误的帖子之后,不仅要维护广播组的问题和答案,还要检查已检查的广播?

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

我已经四处寻找,但没有找到一个完全相同的答案。这个很接近: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。

2 个答案:

答案 0 :(得分:0)

由于您未发送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]之类的注释来执行您已经手动执行的验证。

答案 1 :(得分:0)

  

这将有效。

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() ;
        }
    } 
}
}