【问题标题】:How do I make ASP.NET MVC 3 render objects with complex types in the auto-generated views?如何在自动生成的视图中使 ASP.NET MVC 3 呈现具有复杂类型的对象?
【发布时间】:2011-11-01 03:09:18
【问题描述】:

我的模型类具有复杂类型的属性项(即其他模型类)。当我从 Visual Studio 自动生成视图时,如何才能正确显示这些类(包含在顶级类中)?

基本上,如何将http://bradwilson.typepad.com/blog/2009/10/aspnet-mvc-2-templates-part-4-custom-object-templates.html 更新为 ASP.NET MVC 3?

TIA,
本杰

【问题讨论】:

  • 是的,你是对的,谢谢 - 我只是错过了那部分。如果您将其作为答案提交,我会将其标记为正确...谢谢。

标签: c# asp.net asp.net-mvc asp.net-mvc-3 c#-4.0


【解决方案1】:

来吧,自己努力一点,说说你遇到了什么困难!否则你怎么能学到东西?

Views/Home/Index.cshtml:

@model SampleModel
<h3>Details</h3>
<fieldset style="padding: 1em; margin: 0; border: solid 1px #999;">
    @Html.DisplayForModel()
</fieldset>
<p>@Html.ActionLink("Edit", "Edit")</p>

Views/Home/Edit.cshtml:

@model SampleModel
<h3>Edit</h3>
@using (Html.BeginForm()) 
{
    <fieldset style="padding: 1em; margin: 0; border: solid 1px #999;">
        @Html.ValidationSummary("Broken stuff:")
        @Html.EditorForModel()
        <input type="submit" value="  Submit  " />
    </fieldset>
}
<p>@Html.ActionLink("Details", "Index")</p>

Views/Shared/DisplayTemplates/Object.cshtml:

@model object
@if (Model == null) 
{
    @ViewData.ModelMetadata.NullDisplayText
} 
else if (ViewData.TemplateInfo.TemplateDepth > 1) 
{
    @ViewData.ModelMetadata.SimpleDisplayText
} 
else 
{
    <table cellpadding="0" cellspacing="0" border="0">
    @foreach (var prop in ViewData.ModelMetadata.Properties.Where(pm => pm.ShowForDisplay && !ViewData.TemplateInfo.Visited(pm))) 
    {
        if (prop.HideSurroundingHtml) 
        {
            @Html.Display(prop.PropertyName)
        }
        else 
        {
            <tr>
                <td>
                    <div class="display-label" style="text-align: right;">
                        @prop.GetDisplayName()
                    </div>
                </td>
                <td>
                    <div class="display-field">
                        @Html.Display(prop.PropertyName)
                    </div>
                </td>
            </tr>
        }
    }
    </table>
}

Views/Shared/EditorTemplates/Object.cshtml:

@model object
@if (ViewData.TemplateInfo.TemplateDepth > 1) 
{
    @ViewData.ModelMetadata.SimpleDisplayText
} 
else 
{
    <table cellpadding="0" cellspacing="0" border="0">
    @foreach (var prop in ViewData.ModelMetadata.Properties.Where(pm => pm.ShowForEdit && !ViewData.TemplateInfo.Visited(pm))) 
    {
        if (prop.HideSurroundingHtml) 
        {
            @Html.Editor(prop.PropertyName)
        } 
        else 
        {
            <tr>
                <td>
                    <div class="editor-label" style="text-align: right;">
                        @(prop.IsRequired ? "*" : "")
                        @Html.Label(prop.PropertyName)
                    </div>
                </td>
                <td>
                    <div class="editor-field">
                        @Html.Editor(prop.PropertyName)
                        @Html.ValidationMessage(prop.PropertyName, "*")
                    </div>
                </td>
            </tr>
        }
    }
    </table>
}

【讨论】:

  • 这似乎引入了一个错误,其中名称匹配 ViewBagViewData 属性的视图模型属性被覆盖。例如,名为Title 的属性将被页面标题覆盖。
【解决方案2】:

您是否要求升级到 razor 语法?否则它应该仍然可以在 mvc 3 中工作。只需将代码放在 Views/Shared/EditorTemplates/Object.ascx 中的示例中即可

【讨论】:

    【解决方案3】:

    假设您有一个视图模型,其属性返回一个对象列表,例如

    public class Product
    {
        public int ProductId { get; set; }
        public string Description { get; set; }
        public List<Detail> Details { get; set; }
    }
    

    然后您希望生成使用此模型的视图。这是您的操作方法

    public ViewResult Edit(int productId)
    {
       Product product = contextDB.Products.FirstOrDefault(p => p.ProductId == productId);
    
       return View("Edit", product);
    }
    

    生成的代码将如下所示(不完整)

    @using (Html.BeginForm()) {
        @Html.ValidationSummary(true)
        <fieldset>
            <legend>MyViewModel</legend>
    
            <div class="editor-label">
                @Html.LabelFor(model => model.ProductId)
            </div>
            <div class="editor-field">
                @Html.EditorFor(model => model.ProductId)
                @Html.ValidationMessageFor(model => model.ProductId)
            </div>
    
        ...
        <fieldset>
    }
    

    默认情况下,生成的代码不会包含 List 属性的任何代码。 Razor 视图引擎代码生成器只深入到模型的属性。您可以编写访问视图中的详细信息列表的代码,但它必须是自定义代码。

    【讨论】:

    • 如何编写代码来显示包括所有后代在内的整个属性树?
    • 您必须遍历所有属性和嵌入对象,并在视图中使用它们自己的属性或嵌入对象列表及其属性。如果您希望在模型中嵌入模型,您可能希望使嵌入模型成为局部视图的模型。我绝对不会在视图中放置大量 C# 代码来迭代嵌入式模型。
    猜你喜欢
    • 1970-01-01
    • 2011-07-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多