Две модели в одном представлении в ASP MVC 3 - PullRequest
90 голосов
/ 05 апреля 2011

У меня есть 2 модели:

public class Person
{
    public int PersonID { get; set; }
    public string PersonName { get; set; }
}
public class Order
{
    public int OrderID { get; set; }
    public int TotalSum { get; set; }
}

Я хочу редактировать объекты ОБА классов в ОДНОМ представлении, поэтому мне нужно что-то вроде:

@model _try2models.Models.Person
@model _try2models.Models.Order

@using(Html.BeginForm())
{
    @Html.EditorFor(x => x.PersonID)
    @Html.EditorFor(x => x.PersonName)
    @Html.EditorFor(x=>x.OrderID)
    @Html.EditorFor(x => x.TotalSum)
}

Это, конечно, не работает: в файле .cshtml разрешен только один оператор 'model'. Может быть, есть какое-то решение?

Ответы [ 12 ]

110 голосов
/ 05 апреля 2011

Создайте модель родительского представления, которая содержит обе модели.

public class MainPageModel{
    public Model1 Model1{get; set;}
    public Model2 Model2{get; set;}
}

Таким образом, вы можете добавить дополнительные модели позже с минимальными усилиями.

50 голосов
/ 11 декабря 2012

Чтобы использовать кортеж, вам нужно сделать следующее, в представлении измените модель на:

@model Tuple<Person,Order>

, чтобы использовать методы @html, вам нужно сделать следующее, то есть:

@Html.DisplayNameFor(tuple => tuple.Item1.PersonId)

или

@Html.ActionLink("Edit", "Edit", new { id=Model.Item1.Id }) |

Item1 указывает первый параметр, переданный методу Tuple, и вы можете использовать Item2 для доступа ко второй модели и т. Д.

в контроллере, который необходимо создатьпеременную типа Tuple и затем передайте ее представлению:

    public ActionResult Details(int id = 0)
    {
        Person person = db.Persons.Find(id);
        if (person == null)
        {
            return HttpNotFound();
        }
        var tuple = new Tuple<Person, Order>(person,new Order());

        return View(tuple);
    }

Другой пример: Несколько моделей в представлении

48 голосов
/ 26 сентября 2011

Другой вариант, для которого нет необходимости создавать собственную модель, - это использовать Tuple <> .

@model Tuple<Person,Order>

Это не так чисто, как создание нового класса, который содержит оба, согласно ответу Энди, но он жизнеспособен.

10 голосов
/ 05 апреля 2011

Если вы любите иметь очень плоские модели, просто для поддержки вида вы должны создать модель, специфичную для этого конкретного вида ...

public class EditViewModel
    public int PersonID { get; set; }
    public string PersonName { get; set; }
    public int OrderID { get; set; }
    public int TotalSum { get; set; }
}

Многие люди используют AutoMapper для сопоставления своихдоменные объекты к их плоским представлениям.

Идея модели представления состоит в том, что она просто поддерживает представление - и ничего больше.У вас есть один для каждого представления, чтобы убедиться, что он содержит только то, что требуется для этого представления, а не множество свойств, которые вы хотите для других представлений.

5 голосов
/ 20 апреля 2016

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

Вы делаете свой большой класс, который содержит 2 класса, согласно @ ответу Эндрю.

public class teamBoards{
    public Boards Boards{get; set;}
    public Team Team{get; set;}
}

Затем в вашем контроллере вы заполняете 2 модели. Иногда вам нужно заполнить только один. Затем, в ответе, вы ссылаетесь на большую модель, и она переводит 2 с собой в представление.

            TeamBoards teamBoards = new TeamBoards();


        teamBoards.Boards = (from b in db.Boards
                               where b.TeamId == id
                               select b).ToList();
        teamBoards.Team = (from t in db.Teams
                              where t.TeamId == id
                          select t).FirstOrDefault();

 return View(teamBoards);

Вверху представления

@model yourNamespace.Models.teamBoards

Затем загрузите ваши входные данные или дисплеи, ссылающиеся на содержимое большой модели:

 @Html.EditorFor(m => Model.Board.yourField)
 @Html.ValidationMessageFor(m => Model.Board.yourField, "", new { @class = "text-danger-yellow" })

 @Html.EditorFor(m => Model.Team.yourField)
 @Html.ValidationMessageFor(m => Model.Team.yourField, "", new { @class = "text-danger-yellow" })

А. , , Обратно на ранчо, когда приходит Почта, укажите Большой класс:

 public ActionResult ContactNewspaper(teamBoards teamboards)

и использовать то, что вернули модели:

string yourVariable = teamboards.Team.yourField;

Возможно, в классе есть что-то от DataAnnotation Validation и, возможно, поместите if (ModelState.IsValid) в верхней части блока сохранения / редактирования. , ,

4 голосов
/ 09 июня 2015

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

Использование Employee в качестве примера модели:

@model Employee

На самом деле рассматривается как.

@{ var Model = ViewBag.model as Employee; }

Таким образом, метод View (employee) устанавливает вашу модель на ViewBag, а затем ViewEngine приводит ее.

Это означает, что

ViewBag.departments = GetListOfDepartments();
    return View(employee);

Может использоваться как,

            @model  Employee
        @{
                var DepartmentModel = ViewBag.departments as List<Department>;
        }

По сути, вы можете использовать все, что есть в вашем ViewBag, в качестве "Модели", потому что так оно и работает. Я не говорю, что это архитектурно идеально, но это возможно.

3 голосов
/ 12 августа 2014

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

Лично я бы просто добавил их в одну модель, но я так и сделаю:

public class xViewModel
{
    public int PersonID { get; set; }
    public string PersonName { get; set; }
    public int OrderID { get; set; }
    public int TotalSum { get; set; }
}

@model project.Models.Home.xViewModel

@using(Html.BeginForm())
{
    @Html.EditorFor(x => x.PersonID)
    @Html.EditorFor(x => x.PersonName)
    @Html.EditorFor(x => x.OrderID)
    @Html.EditorFor(x => x.TotalSum)
}
1 голос
/ 05 апреля 2011

Вы можете использовать шаблон презентации http://martinfowler.com/eaaDev/PresentationModel.html

Эта модель представления "Представление" может содержать как персона, так и порядок. Этот новый класс
может быть моделью, на которую ссылается ваше представление.

0 голосов
/ 25 июня 2019

Помимо одной модели ракурса в asp.net вы также можете создать несколько частичных ракурсов и назначить разные ракурсы модели для каждого ракурса, например:

   @{
        Layout = null;
    }

    @model Person;

    <input type="text" asp-for="PersonID" />
    <input type="text" asp-for="PersonName" />

, а затем другой частичный ракурс Модель для модели заказа

    @{
        Layout = null;
     }

    @model Order;

    <input type="text" asp-for="OrderID" />
    <input type="text" asp-for="TotalSum" />

затем на главном экране загрузите оба частичных вида на

<partial name="PersonPartialView" />
<partial name="OrderPartialView" />
0 голосов
/ 04 апреля 2016

Надеюсь, вы найдете это полезным !!

Я использую ViewBag For Project и Model для задачи, поэтому таким образом я использую две модели в одном представлении и в контроллере я определил значение или данные Viewbag

List<tblproject> Plist = new List<tblproject>();
            Plist = ps.getmanagerproject(c, id);

            ViewBag.projectList = Plist.Select(x => new SelectListItem
            {
                Value = x.ProjectId.ToString(),
                Text = x.Title
            });

и с точки зрения tbltask и projectlist мои две модели различий

@ {

IEnumerable<SelectListItem> plist = ViewBag.projectList;

} @model List

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...