【问题标题】:MVC DisplayFor templates seem to quit working if the same model is reused within the template如果在模板中重复使用相同的模型,MVC DisplayFor 模板似乎会停止工作
【发布时间】:2012-05-23 02:14:43
【问题描述】:

我的情况很奇怪。我有一个模型和两个模板,它们都是这个模型类型的强类型。模板是嵌套的,或者换句话说,我在第一个模板中的第二个模板上使用 DisplayFor。如果我使用与第一个模板关联的模型,则在第二个模板的 DisplayFor 调用中,第二个模板不会呈现。如果我使用相同模型类型的另一个实例,一切正常。似乎对与嵌套模板关联的模型进行了某种循环检查。

型号:

public class MyModel
{
    public string Value { get; set; }
    public MyModel Copy
    {
        get { return (MyModel) this.MemberwiseClone(); }
    }

    public MyModel MySelf
    {
        get { return this; }
    }
}

显示模板1:

@model TestNestedTemplateSameReference.Models.MyModel

<div>Model1</div>
<div>@Model.Value</div>
<div>@Html.DisplayFor(x=>x, "ModelTemplate2")</div>

显示模板2:

@model TestNestedTemplateSameReference.Models.MyModel

<div>Model2</div>
<div>@Model.Value</div>

有趣的是,如果不是调用

@Html.DisplayFor(x=>x, "ModelTemplate2")

我用 Copy 属性调用它

<div>@Html.DisplayFor(x=>x.Copy, "ModelTemplate2")</div>

一切正常,因为 MyModel 类的实际实例不同。

有谁知道为什么这样做。是否有可行的解决方法。看起来这是一种完全合法的用法,不应导致堆栈溢出或任何类似问题。我可以看到如何使用它来防止没有模板名称的 DisplayFor 调用循环,但是如果我指定模板名称,它似乎应该可以正常工作。

将同一个模型绑定到多个 EditFor 模板似乎很危险,但 DisplayFor 似乎是安全的。

我当然可以为嵌套级别创建一个单独的模型,但那是创建冗余类。

感谢任何帮助。

【问题讨论】:

    标签: asp.net-mvc


    【解决方案1】:

    如果您尝试执行的操作有效,则会在通过 Copy 方法创建对象后导致堆栈溢出作为对象。每个对象都会依次创建自己的新副本,您很快就会耗尽内存或耗尽堆栈。

    默认模板在显示属性之前执行此方法

    bool ShouldShow(ModelMetadata metadata) {
        return metadata.ShowForEdit
            && metadata.ModelType != typeof(System.Data.EntityState)
            && !metadata.IsComplexType
            && !ViewData.TemplateInfo.Visited(metadata);
    }
    

    我的猜测是它会触发 IsComplexType 或 TemplateInfo.Visited。

    这里有更多信息:

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

    【讨论】:

    • 为什么要这样做?我没有无限嵌套循环。模板的嵌套在两个之后停止。事实上,如果这种行为是由于对无限嵌套的保护,那么测试似乎应该在模板名称或模板实例上而不是模型上。事实上,使用 .Copy 属性就可以了。
    • 神秘人,您知道是否可以覆盖 ShouldShow 行为,或者是否有任何扩展点可以用来改变行为?
    • @EugeneTsimberg - 是的,您可以使用新的对象模板覆盖它。如果您下载 MVC3 Futures 的源代码,它包含内部使用的默认模板。如果您将 Ojbect.ascx 放在 ~/Views/Shared/EditorTemplates 中,然后对其进行修改,它将改用它。
    猜你喜欢
    • 1970-01-01
    • 2013-08-23
    • 1970-01-01
    • 1970-01-01
    • 2011-04-28
    • 1970-01-01
    • 1970-01-01
    • 2023-01-02
    • 2011-08-08
    相关资源
    最近更新 更多