Dwa modele w jednym widoku w ASP MVC 3

Mam 2 modele:

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

Chcę edytować obiekty obu klas w jednym widoku, więc potrzebuję czegoś w stylu:

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

To oczywiście nie działa: dozwolone jest tylko jedno wyrażenie " modelowe "wplik cshtml. Może jest jakieś obejście?

Author: Erik Funkenbusch, 2011-04-05

11 answers

Utwórz model widoku nadrzędnego, który zawiera oba modele.

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

W ten sposób można dodać kolejne modele w późniejszym terminie przy bardzo minimalnym wysiłku.

 104
Author: Andrew,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-04-05 10:51:28

Aby użyć krotki, musisz wykonać następujące czynności, w widoku Zmień model na:

@model Tuple<Person,Order>

Aby używać metod @html należy wykonać następujące czynności:

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

Lub

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

Item1 wskazuje pierwszy parametr przekazany do metody Tupel i można użyć Item2, aby uzyskać dostęp do drugiego modelu i tak dalej.

W kontrolerze musisz utworzyć zmienną typu krotka, a następnie przekazać ją do widoku:

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

Inny przykład: wiele modeli w widok

 49
Author: Hamid,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:54:44

Inną opcją, która nie ma potrzeby tworzenia modelu niestandardowego, jest użycie krotki .

@model Tuple<Person,Order>

To nie jest tak czyste, jak tworzenie nowej klasy, która zawiera oba, zgodnie z odpowiedzią Andi, ale jest wykonalne.

 47
Author: Bobson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-09-26 16:58:40

Jeśli jesteś fanem bardzo płaskich modeli, tylko po to, aby wspierać widok, powinieneś stworzyć model specyficzny dla tego widoku...

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

Wiele osób używa Automapp do mapowania obiektów z domeny do płaskich widoków.

Ideą modelu widoku jest to, że po prostu obsługuje widok - nic więcej. Jeden Widok ma zapewnić, że zawiera tylko to, co jest wymagane dla tego widoku - a nie ładuje właściwości, które chcesz dla innych widoków.

 10
Author: user75525,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-04-05 10:59:29

Po prostu utwórz pojedynczy model widoku ze wszystkimi potrzebnymi informacjami w nim, zwykle to, co robię, to tworzenie modelu dla każdego widoku, więc mogę być konkretny dla każdego widoku, albo To, albo stworzyć model nadrzędny i dziedziczyć go. Lub zrobić model, który zawiera oba widoki.

Osobiście dodałbym je do jednego modelu, ale tak to robię:

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)
}
 3
Author: Michael,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-08-12 10:28:07

W rzeczywistości istnieje sposób na użycie dwóch lub więcej modeli w jednym widoku bez zawijania ich w klasę, która zawiera oba.

Wykorzystanie pracownika jako przykładowego modelu:

@model Employee

Jest właściwie traktowany jak.

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

Więc metoda View(employee) ustawia twój model na ViewBag, a następnie viewengine go odlewa.

Oznacza to, że

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

Może być używany jak,

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

Zasadniczo możesz użyć tego, co jest w Twoim widoku jako "modelu", ponieważ to jak to działa. Nie mówię, że jest to architektonicznie idealne, ale jest to możliwe.

 3
Author: Alex Tselevich,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-09 14:18:43

Ok, każdy ma sens i wziąłem wszystkie kawałki i umieścić je tutaj, aby pomóc początkującym jak ja, którzy potrzebują początku do końca wyjaśnienia.

Tworzysz swoją wielką klasę, która ma 2 klasy, zgodnie z odpowiedzią @ Andrew.

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

Następnie w kontrolerze wypełniasz 2 modele. Czasami wystarczy wypełnić tylko jeden. Następnie w zamian odwołujesz się do dużego modelu i zabierze ze sobą 2 wewnątrz do widoku.

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

U góry widoku

@model yourNamespace.Models.teamBoards

Wtedy załaduj swoje wejścia lub wyświetlacze odwołujące się do zawartości dużych modeli:

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

I. . . .po powrocie na ranczo, Gdy Pojawi Się Post, odwołaj się do wielkiej klasy:

 public ActionResult ContactNewspaper(teamBoards teamboards)

I skorzystaj z tego, co model(y) zwrócił:

string yourVariable = teamboards.Team.yourField;

Prawdopodobnie mają jakieś dane do sprawdzania poprawności w klasie i prawdopodobnie wstawiają if (ModelState.IsValid) u góry bloku Zapisz/edytuj. . .

 2
Author: JustJohn,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-20 01:32:13

Możesz użyć wzorca prezentacji http://martinfowler.com/eaaDev/PresentationModel.html

Ten model prezentacji "Widok" może zawierać zarówno osobę, jak i Zamówienie, ten nowy
klasa może być modelem, do którego odwołujesz się w widoku.

 1
Author: James Kyburz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-04-05 10:53:17

Innym sposobem, o którym nigdy się nie mówi, jest Utwórz widok w MSSQL ze wszystkimi danymi, które chcesz przedstawić. Następnie użyj LINQ do SQL lub cokolwiek, aby to zmapować. W kontrolerze zwróć go do widoku. Załatwione.

 0
Author: hidden,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-09-13 21:16:47

Nie możesz zadeklarować dwóch modeli w jednym widoku, spróbuj użyć Html.Action("Person", "[YourController]") & Html.Action("Order", "[YourController]").

Powodzenia.
 0
Author: Jimmy Mac,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-13 07:38:34

Mam nadzieję, że ci to pomoże !!

Używam ViewBag dla projektu i modelu dla zadania, więc w ten sposób używam dwóch modeli w jednym widoku i w kontrolerze zdefiniowałem wartość lub dane 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
            });

I w widoku tbltask i projectlist to moje dwa modele diff

@{

IEnumerable<SelectListItem> plist = ViewBag.projectList;

} @lista modeli

 -1
Author: Muhafil Saiyed,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-04 10:11:04