web-dev-qa-db-ja.com

ASP MVC 3の1つのビューに2つのモデル

私には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ファイルでは1つの「モデル」ステートメントのみが許可されます。回避策がありますか?

90
Smarty

両方のモデルを含む親ビューモデルを作成します。

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

これにより、後日、最小限の労力でモデルを追加できます。

111
Andrew

タプルを使用するには、次を実行する必要があります。ビューでモデルを次のように変更します。

@model Tuple<Person,Order>

@htmlメソッドを使用するには、次のことを行う必要があります。

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

または

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

Item1は、Tupleメソッドに渡される最初のパラメーターを示し、Item2を使用して2番目のモデルにアクセスできます。

コントローラーで、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);
    }

別の例: ビュー内の複数のモデル

50
Hamid Tavakoli

カスタムモデルを作成する必要がない別のオプションは、 Tuple <> を使用することです。

@model Tuple<Person,Order>

Andiの答えによると、両方を含む新しいクラスを作成するほどきれいではありませんが、実行可能です。

48
Bobson

ビューをサポートするためだけに、非常にフラットなモデルを持つことが好きな場合は、この特定のビューに固有のモデルを作成する必要があります...

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

多くの人がAutoMapperを使用して、ドメインオブジェクトからフラットビューにマッピングします。

ビューモデルの考え方は、ビューをサポートするだけであり、他には何もありません。ビューごとに1つあり、他のビューに必要なプロパティのロードではなく、そのビューに必要なもののみが含まれるようにします。

10
Fenton

oK.

@Andrewの答えに従って、2つのクラスを保持する大きなクラスを作成します。

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

次に、コントローラーで2つのモデルを埋めます。場合によっては、1つだけ入力する必要があります。次に、戻り値で、大きなモデルを参照します。これにより、内部の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)を保存/編集ブロックの先頭に配置します。 。 。

5
JustJohn

実際、1つのビューで2つ以上のモデルを使用する方法があり、両方を含むクラスにモデルをラップすることはありません。

従業員をサンプルモデルとして使用する:

@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にあるものはすべて「モデル」として使用できます。これがアーキテクチャ的に理想的であると言っているわけではありませんが、可能です。

4
Alex Tselevich

必要なすべての情報を含む単一のビューモデルを作成するだけです。通常は、すべてのビューに対してモデルを作成し、すべてのビューを特定するか、親モデルを作成して継承します。 ORは、両方のビューを含むモデルを作成します。

個人的には、それらを1つのモデルに追加するだけですが、その方法は次のとおりです。

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
Michael

プレゼンテーションパターンを使用できます http://martinfowler.com/eaaDev/PresentationModel.html

このプレゼンテーションの「表示」モデルには、個人と注文の両方を含めることができます。
クラスは、ビューが参照するモデルにすることができます。

1
James Kyburz

1つのビューで2つのモデルを宣言することはできません。Html.Action("Person", "[YourController]")Html.Action("Order", "[YourController]")を使用してみてください。

幸運を。

0
Jimmy Mac

Asp.netの1つのビューモデルのほかに、複数の部分ビューを作成し、すべてのビューに異なるモデルビューを割り当てることもできます。次に例を示します。

   @{
        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
shojaeddin

決して語られないもう1つの方法は、表示するすべてのデータを使用してMSSQLでビューを作成することです。次に、LINQ to SQLなどを使用してマッピングします。コントローラーでビューに戻します。できた.

0
hidden