嵌套 MVC3 模型既不验证也不绑定

发布于 2024-12-28 10:02:44 字数 1796 浏览 2 评论 0原文

我有一个 RegisterModel,由 5 个 SecretQuestionAndAnswerModel 模型组成

public class RegisterModel
{
    public SecretQuestionAndAnswerModel SecretQuestion1 { get; set; }
    public SecretQuestionAndAnswerModel SecretQuestion2 { get; set; }
    public SecretQuestionAndAnswerModel SecretQuestion3 { get; set; }
    public SecretQuestionAndAnswerModel SecretQuestion4 { get; set; }
    public SecretQuestionAndAnswerModel SecretQuestion5 { get; set; }
}

public class SecretQuestionAndAnswerModel
{
        public SecretQuestionTypeModel Type { get; set; }

        [Required(ErrorMessage = "Please choose a question.")]
        public int Id { get; set; }
        public string Question { get; set; }

        [Required]
        [StringLength(20)]
        public string Answer { get; set; }

        [Display(Name = "Select Question")]
        public IEnumerable<SelectListItem> DefaultQuestions { get; set; }
}

在我的主 Register.cshtml 上,我包含每个问题,如下所示:

@Html.Partial("_QuestionAndAnswer", Model.SecretQuestion1, new ViewDataDictionary { { "Index", 1 }})

并且该部分看起来像:

<div class="input">
        @{
            @Html.DropDownListFor(m => Model.Id, Model.DefaultQuestions, "(Please choose one)") 
            @Html.ValidationMessageFor(m => Model.Id)

            @Html.TextBoxFor(m => m.Answer) 
            @Html.ValidationMessageFor(m => m.Answer)
        }
</div>

但是在验证时,所有 5 个问题都表现为一个:换句话说,如果我选择一个问题并输入第一个秘密问题的答案,那么它们都会通过验证,反之亦然...

此外,在发布到 HttpPost Register 方法时,

public ActionResult Register(RegisterModel model) { ...

model.SecretQuestion1 始终为 null。他们都是。如何进行这种嵌套模型绑定?我以为这样就可以了。

I have a RegisterModel, composed of 5 SecretQuestionAndAnswerModel models

public class RegisterModel
{
    public SecretQuestionAndAnswerModel SecretQuestion1 { get; set; }
    public SecretQuestionAndAnswerModel SecretQuestion2 { get; set; }
    public SecretQuestionAndAnswerModel SecretQuestion3 { get; set; }
    public SecretQuestionAndAnswerModel SecretQuestion4 { get; set; }
    public SecretQuestionAndAnswerModel SecretQuestion5 { get; set; }
}

and

public class SecretQuestionAndAnswerModel
{
        public SecretQuestionTypeModel Type { get; set; }

        [Required(ErrorMessage = "Please choose a question.")]
        public int Id { get; set; }
        public string Question { get; set; }

        [Required]
        [StringLength(20)]
        public string Answer { get; set; }

        [Display(Name = "Select Question")]
        public IEnumerable<SelectListItem> DefaultQuestions { get; set; }
}

On my main Register.cshtml, I include each question like this:

@Html.Partial("_QuestionAndAnswer", Model.SecretQuestion1, new ViewDataDictionary { { "Index", 1 }})

and that partial looks like:

<div class="input">
        @{
            @Html.DropDownListFor(m => Model.Id, Model.DefaultQuestions, "(Please choose one)") 
            @Html.ValidationMessageFor(m => Model.Id)

            @Html.TextBoxFor(m => m.Answer) 
            @Html.ValidationMessageFor(m => m.Answer)
        }
</div>

But on validation, all 5 questions behave as one: in other words if I select a question and type in an answer for the 1st secret question then they all pass validation, and vice versa...

Also, on posting to the HttpPost Register method

public ActionResult Register(RegisterModel model) { ...

the model.SecretQuestion1 is always null. All of them are. How do you do this sort of nested model-binding? I thought this would work ok.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

离笑几人歌 2025-01-04 10:02:44

如果您查看生成的 HTML,原因就很明显了。每个项目都具有相同的 ID 和相同的名称。模型绑定器没有简单的方法来区分哪个是哪个。

这是部分视图和模板之间差异的一个主要示例。模板有额外的逻辑来处理这种情况。

您应该创建一个 SecretQuestionAndAnswerModel 模板并使用

@EditorFor(x => x.SecretQuestion1)

如果您不确定模板的工作原理,请阅读以下内容:

http://bradwilson.typepad.com/blog/2009/10/aspnet-mvc-2-templates-part-1-introduction.html

The reason is pretty obvious if you look at the generated HTML. Each item has the same ID, and the same name. There is no easy way for the model binder to tell which is which.

This is a prime example of the difference between a partial view, and a template. Templates have extra logic to deal with this situation.

You should, instead create a SecretQuestionAndAnswerModel template and use

@EditorFor(x => x.SecretQuestion1)

If you are unsure of how templates work, read this:

http://bradwilson.typepad.com/blog/2009/10/aspnet-mvc-2-templates-part-1-introduction.html

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文