Несколько объектов в одностраничной форме

#c# #asp.net-mvc #entity-framework #model-view-controller

#c# #asp.net-mvc #entity-framework #модель-представление-контроллер

Вопрос:

У меня проблема, из-за которой я не могу получить более одной модели для отображения в представлении, в частности в форме. Подход, который я использовал до сих пор, заключается в использовании одного «родительского» представления для хранения нескольких частичных представлений, относящихся к различным моделям (с использованием EF6, VS13).

Однако из-за неправильной реализации или понимания я, похоже, не могу заставить это работать, поскольку я продолжаю получать сообщение об ошибке, что каждое представление может относиться только к одной модели.

Модели

NewHire:

 namespace HROnboarding.Domain.Entities
{
    public class NewHire
    {
        public int NewHireId { get; set; }

        [Required]
        [DisplayName("First Name")]
        public string FirstName { get; set; }
        [Required]
        [DisplayName("Last Name")]
        public string LastName { get; set; }
        public string Department { get; set; }
        public string Position { get; set; }
        [DisplayName("Needs Phone")]
        public bool NeedsPhone { get; set; }
        [DisplayName("Needs Computer")]
        public bool NeedsComputer { get; set; } //Enables SoftwareNeeded, External Devices(Keyboard, mouse, docking station, etc), Resource Permission(text box?), Email groups
        [DisplayName("Needs Credit Card")]
        public bool NeedsCredit { get; set; }
    }
}
  

Требуется программное обеспечение:

 namespace HROnboarding.Domain.Entities
{
    public class SoftwareNeeded
    {
        //Primitive Properties
        public int SoftwareNeededId { get; set; }
        public string SoftwareName { get; set; } //piece of software (GIMP, VS13, etc)
        public bool IsNeeded { get; set; } //whether or not it is needed by the user
    }
}
  

Контроллеры

NewHireController:

 namespace HROnboarding.WebUI.Controllers    
{
    public class NewHireController : Controller
    {
        private INewHiresRepository repository;
        public NewHireController(INewHiresRepository newHireRepository)
        {
            //instantiate repository
            this.repository = newHireRepository;
        }
        //
        // GET: /NewHire/
        public ViewResult Index()
        {
            return View(repository.NewHires);
        }

        public ViewResult NewHiresView()
        {
            return View(repository.NewHires);
        }
    }
}
  

Примечание: существует также соответствующий SoftwareController, идентичный NewHireController .

Эти модели соответствуют интерфейсам (репозиториям), которые выглядят примерно так для каждой модели:

 namespace HROnboarding.Domain.Interfaces
{
    public interface INewHiresRepository
    {
        IEnumerable<NewHire> NewHires { get; }
        int SaveNewHire(NewHire newHire);
        NewHire GetById(int Id);

    }
}
  

As I said, I’m attempting to use partial views for each model:

 @model IEnumerable<HROnboarding.Domain.Entities.NewHire>

@if (Model != null)
{
    <div>
        <table>
            <thead>
                <tr>
                    <th>
                        First Name
                    </th>
                    <th>
                        Last Name
                    </th>
                    <th>
                        Department
                    </th>

                </tr>
            </thead>
            <tbody>
                @foreach (var item in Model)
                {
                    <tr>
                        <td>
                            @item.FirstName
                               .
                               .
                               .
  

Я использую одно из этих частичных представлений для каждой модели, объединяя их в ссылки через первичное индексное представление следующим образом:

 @using HROnboarding.Domain.Entities
@using HROnboarding.Domain.Interfaces
@model IEnumerable<HROnboarding.Domain.Entities.NewHire>

<h2>List</h2>
<p>
    <div>
        @Html.Partial("NewHiresView")
    </div>
    <div>
        @*@Html.Partial("Softwares")*@ @*<-------Can't just add this in?*@
    </div>
</p>
@*<p>
    @Html.ActionLink("Create New", "Create")
</p>*@
@*<table class="table">
    <tr>
        <th>
            @Html.DisplayNameFor(model => model.FirstName)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.LastName)
  

Но когда я собираюсь добавить различные части в представление индекса, я могу добавить только NewHire. Когда я добавляю представление программного обеспечения, оно выдает необработанное исключение:

Дополнительная информация: элемент модели, переданный в словарь, имеет тип ‘System.Data.Entity.DbSet 1[HROnboarding.Domain.Entities.NewHire]',
but this dictionary requires a model item of type
'System.Collections.Generic.IEnumerable
1[Архивирование.Домен.Объекты.Требуется программное обеспечение]’

Как я уже сказал, я, должно быть, упускаю здесь что-то фундаментальное, поскольку чувствую, что делаю это слишком сложным. Также не уверен, что это «слишком много» справочной информации, но я надеюсь, что мой вопрос понятен.

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

1. По определению, у вас может быть только одна модель, не существует такого понятия, как несколько моделей для каждого представления. Если вам нужно отобразить данные из нескольких разных классов, вы можете создать viewmodel, специфичный для вашего представления, и включить те классы, которые вы хотите отобразить, в качестве членов вашей viewmodel. И вы, вероятно, захотите использовать шаблоны редактора вместо частичных представлений.

Ответ №1:

Я делаю что-то то же самое, с той лишь разницей, что я передаю только одну модель представления в свой основной вид, каждая из них затем отображается с использованием

@Html.Partial("ViewName", Model)

Модель veiw представляет собой совокупность некоторых объектов домена. Некоторые из этих представлений содержатся в одной форме, что приводит к возврату полной модели. и другие поддерживают ajax и отправляют обратно только части ViewModel в виде объектов JSON.

Возможно, попробуйте упростить свои представления и использовать модели представлений с использованием частичных

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

1. Итак, у вас есть модель представления, которая содержит все классы моделей, которые, в свою очередь, отображаются в основном представлении?

2. @AlGoreRhythm не все модели, а только те модели, о которых заботится текущая структура представления. Например, редактируемый объект и списки, содержащие выпадающие значения, которые должны отображаться в представлении.

3. Правильно, но для моего примера я хочу, чтобы все это было в одной форме. Форма использует все объекты данных перед отправкой. Или вы имеете в виду те, которые непосредственно соответствуют данным в том же «поле»?

4. Нет, тогда я бы использовал все объекты, которые вам требуются, внутри этой модели one view. Думайте о модели представления как о том, что она говорит, это модель, которая требуется для работы представления. Затем при отправке обратно контроллер принимает ту же модель представления и выполняет сохранение, проверку и т. Д. В модели представления

Ответ №2:

Ваша основная проблема заключается в том, что вы пытаетесь использовать свои объекты данных в качестве моделей представления.

У вас есть два варианта:

Быстро и грязно: передайте свои объекты данных в представление через ViewBag.

«Правильный» MVC: создайте ViewModels для каждого представления. Модели будут включать свойства, которые соответствуют вашим объектам данных

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

1. Есть ли какие-либо ресурсы, которые вы можете связать, которые относятся к моей конкретной ситуации? Я хочу действовать «правильным» способом, но я не уверен, как это сделать. Когда вы говорите viewmodel для каждого представления, будут ли эти viewmodels включать ссылки на мои классы моделей?