0

I have a really strange situation. I have a single Model, and two templates that are both strong-typed on the type of this model. The templates are nested, or in other words, I use DisplayFor on the second Template from within the first template. If I use the model associated with the first template, in the DisplayFor call for the second template, the second template does not render. If I use another instance of the same model type, everything works fine. It seems like there is some sort of cycle checking on the models associated with nested templates.

Model:

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

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

DisplayTemplate1:

@model TestNestedTemplateSameReference.Models.MyModel

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

DisplayTemplate2:

@model TestNestedTemplateSameReference.Models.MyModel

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

Interestingly if instead of calling

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

I call it with the Copy property

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

everything works fine as the actual instance of the MyModel class is different.

Does anyone know why this is done. Is there a viable workaround. It seems like this is a perfectly legitimate usage which shouldnot cause a stack overflow, or any similar issues. I could see how this could be used to protect against cycles for DisplayFor call without template name, but if I specify the template name seems like it should work fine.

It seems like it would be dangerous to bind the same model to multiple EditFor templates, but DisplayFor seems safe.

I can of course create a separate model for nesting level, but that is creating redundand class.

Any help is appreciated.

4

1 回答 1

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

于 2012-05-22T14:37:09.573 回答