#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 # в представление для итерации по встроенной модели.