MVC2-如何获得父母的模式(集装箱)内部模板
-
25-09-2019 - |
题
我在写一MVC2应用程序使用DataAnnotations.我有下列模式:
public class FooModel
{
[ScaffoldColumn("false")]
public long FooId { get; set; }
[UIHint("BarTemplate")]
public DateTime? Bar { get; set;}
}
我想创建一个自定义显示的模板,对吧。我已经创建了以下模板:
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<DateTime?>" %>
<div class="display-label">
<span><%: Html.LabelForModel() %></span>
</div>
<div class="display-field">
<span><%: Html.DisplayForModel()%></span>
<%: Html.ActionLink("Some link", "Action", new { id = ??FooId?? }) %>
</div>
现在,我的问题是 内部模板吧我想访问的另一个酒店从我的模特.我不想创建一个独立的模板FooModel由于我将要硬编码的所有其他FooModel性质。
经过简短调查一个调试器,我可以看出:
this.ViewData.ModelMetadata.ContainerType
是FooModel
(预期)this.ViewData.TemplateInfo
有一个 非公共财产VisitedObjects
(类型System.Collections.Generic.HashSet<object>
) 它包含两个要素:FooModel
和DateTime?
.
怎么我可以访问我FooModel?我不想要破解我的方式使用的反思。
更新:
我已经接受了mootinator的答案,因为它看起来我最好的解决方案,允许类型的安全。我也投赞成票Tx3的答案,因为mootinator的答复为基础。尽管如此,我认为应该有一个更好的支持形式,视在这种情况下,我认为这是相当常见的,在现实世界,但是缺少采样的应用程序。
解决方案
对不起,如果这项建议似乎是愚蠢的,我还没有尝试过,但你能不能做什么Tx3建议而不具有以创建一批新的课程通过确定一般类为参考任何类型的父母你想要的吗?
public class FooModel
{
[ScaffoldColumn("false")]
public long FooId { get; set; }
[UIHint("BarTemplate")]
public ParentedDateTime<FooModel> Bar { get; set;}
public FooModel()
{
Bar = new ParentedDateTime<FooModel>(this);
}
}
public class ParentedDateTime<T>
{
public T Parent {get; set;}
public DateTime? Babar {get; set; }
public ParentedDateTime(T parent)
{
Parent = parent;
}
}
你可以扩大到封任何旧的型 <Parent, Child>
输入通用的,甚至。
会还给你的好处就是你的强类型的模板将用于
Inherits="System.Web.Mvc.ViewUserControl<ParentedDateTime<FooType>>
这样你就不必明确姓名的模板,以在任何地方使用。这是更多的事情是如何打算的工作。
其他提示
也许你可以创建新的课,让我们说UserDateTime,它将包含可空的时间和剩下的你需要的信息。然后你会使用的定义显示的模板UserDateTime和获取信息的要求。
我知道你可能会寻找其他种类的解决方案。
我认为你可以更好地关提取这种功能HtmlHelper呼从父图。
喜欢的东西 RenderSpecialDateTime<TModel>(this HtmlHelper html, Expression<Func<TModel,DateTime?>> getPropertyExpression)
可能会做的工作。
否则,你将要做的像什么Tx3建议。我投赞成票,他的答案,但是发布此作为一种替代方法。
你能不能使用可视数据用字典对象在控制器,然后抓住那个在ViewUserControl?它不会被强类型的但是...你可以写一个帮手要做什么,如果它是空的,并链接到说的例子登录历史的一页,如果它有一个价值。
它会出现的地方之间的视5.0和5.2.2一个"容器"的财产被加入到ModelMetadata类。
但是,因为所有的方法中的一个供应商负责创建元数据(GetMetadataForProperty,创建等)没有容器在他们的签名,该容器中的财产分配只在某些情况下(GetMetadataForProperties和GetMetadataFromProvider根据反映的代码),并在我的情况下,通常是空。
所以我做了是压倒一切的GetMetadataForProperty在一个新的元数据提供者和设有:
public override ModelMetadata GetMetadataForProperty(Func<object> modelAccessor, Type containerType, string propertyName)
{
var propMetaData = base.GetMetadataForProperty(modelAccessor, containerType, propertyName);
Object container = modelAccessor.Target.GetType().GetField("container").GetValue(modelAccessor.Target);
propMetaData.Container = container;
return propMetaData;
}
我知道这是反射但这是相当简明扼要。它会出现MS是纠正这oversite因此,也许它将有可能取代反射代码的未来。