Как мне сделать ASP.NET MVC 3 визуализирует объекты со сложными типами в автоматически сгенерированных представлениях?

#c# #asp.net #asp.net-mvc #asp.net-mvc-3 #c#-4.0

#c# #asp.net #asp.net-mvc #asp.net-mvc-3 #c #-4.0

Вопрос:

У меня есть классы моделей, которые имеют в качестве свойств элементы сложных типов (т. Е. Другие классы моделей). Как я могу сделать так, чтобы при автоматическом создании представлений из Visual Studio эти классы (которые включены в класс верхнего уровня) отображались соответствующим образом?

В принципе, как мне обновить http://bradwilson.typepad.com/blog/2009/10/aspnet-mvc-2-templates-part-4-custom-object-templates.html чтобы ASP.NET MVC 3?

ТИА,
Бенджи

Комментарии:

1. Да, вы правы, спасибо — я просто пропустил эту часть. Если вы отправите это в качестве ответа, я отмечу это правильно… Спасибо.

Ответ №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 amp;amp; !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 amp;amp; !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>
}
 

Комментарии:

1. Похоже, это приводит к ошибке, при которой свойства viewmodel, имена которых совпадают ViewBag , или ViewData свойства переопределяются. Например, вызываемое свойство 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 view engine проникает только в свойства модели. Вы можете написать код, который обращается к списку сведений в представлении, но это должен быть пользовательский код.

Комментарии:

1. Как мне написать этот код для отображения всего дерева свойств, включая всех потомков?

2. Вам придется перебирать все свойства и внедренные объекты с их собственными свойствами или списками внедренных объектов и их свойств внутри представления. Если вы хотите внедрить модель в модель, вы можете сделать встроенную модель моделью для частичного представления. Я бы определенно НЕ стал помещать много кода C # в представление для итерации по встроенной модели.