ASP.NET MVC 3的验证上嵌套对象未按预期 - 验证子对象两次,而不是父对象 [英] ASP.NET MVC 3 Validation on Nested Objects not working as expected - validates child object twice and not parent object

查看:201
本文介绍了ASP.NET MVC 3的验证上嵌套对象未按预期 - 验证子对象两次,而不是父对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想获得ASP.NET MVC 3,以生成复杂的嵌套对象的形式。有一个验证的行为,我发现这是意想不到的,我不知道这是否是一个错误的DefaultModelBinder与否。

I am trying to get ASP.NET MVC 3 to generate forms from complex, nested objects. There is one validation behaviour I found which was unexpected and I am not sure if it's a bug in the DefaultModelBinder or not.

如果我有两个对象,让我们称之为父一OuterObject,它有型InnerObject(孩子)的属性:

If I have two objects, lets call the "parent" one "OuterObject", and it has a property of type "InnerObject" (the child):

    public class OuterObject : IValidatableObject
{
    [Required]
    public string OuterObjectName { get; set; }

    public InnerObject FirstInnerObject { get; set; }

    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        if (!string.IsNullOrWhiteSpace(OuterObjectName) && string.Equals(OuterObjectName, "test", StringComparison.CurrentCultureIgnoreCase))
        {
            yield return new ValidationResult("OuterObjectName must not be 'test'", new[] { "OuterObjectName" });
        }
    }
}

下面是InnerObject:

Here is InnerObject:

    public class InnerObject : IValidatableObject
{
    [Required]
    public string InnerObjectName { get; set; }

    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        if (!string.IsNullOrWhiteSpace(InnerObjectName) && string.Equals(InnerObjectName, "test", StringComparison.CurrentCultureIgnoreCase))
        {
            yield return new ValidationResult("InnerObjectName must not be 'test'", new[] { "InnerObjectName" });
        }
    }
}

您会注意到我把两个验证..只是一些虚拟验证,说一些价值不能等于测试。

You will notice the validation I put on both.. just some dummy validation to say some value can't equal "test".

下面是这将显示(Index.cshtml)的观点:

Here is the view that this will display in (Index.cshtml):

@model MvcNestedObjectTest.Models.OuterObject
@{
    ViewBag.Title = "Home Page";
}

@using (Html.BeginForm()) {
<div>
    <fieldset>
        <legend>Using "For" Lambda</legend>

        <div class="editor-label">
            @Html.LabelFor(m => m.OuterObjectName)
        </div>
        <div class="editor-field">
            @Html.TextBoxFor(m => m.OuterObjectName)
            @Html.ValidationMessageFor(m => m.OuterObjectName)
        </div>

        <div class="editor-label">
            @Html.LabelFor(m => m.FirstInnerObject.InnerObjectName)
        </div>
        <div class="editor-field">
            @Html.TextBoxFor(m => m.FirstInnerObject.InnerObjectName)
            @Html.ValidationMessageFor(m => m.FirstInnerObject.InnerObjectName)
        </div>

        <p>
            <input type="submit" value="Test Submit" />
        </p>
    </fieldset>
</div>
}

..最后这里是HomeController的:

..and finally here is the HomeController:

    public class HomeController : Controller
{
    public ActionResult Index()
    {
        var model = new OuterObject();
        model.FirstInnerObject = new InnerObject();
        return View(model);
    }

    [HttpPost]
    public ActionResult Index(OuterObject model)
    {
        if (ModelState.IsValid)
        {
            return RedirectToAction("Index");
        }
        return View(model);
    }
}

你会发现是,当模型得到由DefaultModelBinder,在InnerObject中的验证方法被打了两拳,但在OuterObject中的验证方法验证不被打到的。

What you will find is that when the model gets validated by the DefaultModelBinder, the "Validate" method in "InnerObject" gets hit twice, but the "Validate" method in "OuterObject" does not get hit at all.

如果您从InnerObject,然后点击OuterObject会被打到一起飞IValidatableObject。

If you take off IValidatableObject from "InnerObject", then the one on "OuterObject" will get hit.

这是一个bug,或者我应该期​​望它的工作呀?如果我期望它,什么是最好的解决方法?

Is this a bug, or should I expect it to work that way? If I should expect it to, what's the best workaround?

推荐答案

我不知道这是MVC 4个问题了,但是......

I am not sure this is a problem with MVC 4 anymore, but...

如果您用于InnerObjects只是做局部视图,他们会正确验证。

If you use partial views made just for your InnerObjects, they will validate correctly.

<fieldset>
    <legend>Using "For" Lambda</legend>

    <div class="editor-label">
        @Html.LabelFor(m => m.OuterObjectName)
    </div>
    <div class="editor-field">
        @Html.TextBoxFor(m => m.OuterObjectName)
        @Html.ValidationMessageFor(m => m.OuterObjectName)
    </div>

    @Html.Partial("_InnerObject", Model.InnerObject)

    <p>
        <input type="submit" value="Test Submit" />
    </p>
</fieldset>

然后添加此部分_InnerObject.cshtml

Then add this partial "_InnerObject.cshtml":

@model InnerObject

    <div class="editor-label">
        @Html.LabelFor(m => m.InnerObjectName)
    </div>
    <div class="editor-field">
        @Html.TextBoxFor(m => m.InnerObjectName)
        @Html.ValidationMessageFor(m => m.InnerObjectName)
    </div>

这篇关于ASP.NET MVC 3的验证上嵌套对象未按预期 - 验证子对象两次,而不是父对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆