Две модели в одном представлении в ASP MVC 3


у меня есть 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)
}

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

11 88

11 ответов:

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

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

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

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

@model Tuple<Person,Order>

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

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

или

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

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

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

    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);
    }

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

другой вариант, который не имеет необходимости создавать пользовательскую модель, - использовать Кортеж.

@model Tuple<Person,Order>

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

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

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

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

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

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

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

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)
}

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

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

@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>;
        }

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

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

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

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 вещи в классе и, вероятно, поставить if(ModelState.IsValid) в верхней части блока сохранения/редактирования. . .

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

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

еще один способ, о котором никогда не говорят, это Создать представление в MSSQL со всеми данными, которые вы хотите представить. Затем используйте LINQ to SQL или что-то еще, чтобы отобразить его. В вашем контроллере верните его в представление. Сделанный.

вы не можете объявить две модели на один вид, попробуйте использовать Html.Action("Person", "[YourController]") & Html.Action("Order", "[YourController]").

удачи.

Я надеюсь, что вы найдете его полезным !!

Я использую ViewBag для проекта и модели для задачи, поэтому таким образом я использую две модели в одном представлении и в контроллере я определил значение 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 мои две модели diff

@{

IEnumerable<SelectListItem> plist = ViewBag.projectList;

} @список моделей