web-dev-qa-db-ja.com

1つのビューでのMVC 5複数モデル

誰かが1つのビュー内で2つのモデルを組み合わせる方法の例を提供できますか?

現在、私はRecordCardと呼ばれるページを持っています:

@model IEnumerable<WebApplication1.Models.Weight>

これは、AccountControllerの次のコードによって提供されます。

public ActionResult RecordCard()
{
    var UserId = User.Identity.GetUserId();
    var weightModel = from m in db.Weights where m.UserId == UserId select m;
    return View(weightModel);
}

RecordCardページには、次のクラスにバインドされたフォームも含まれています。

public class AddWeightModel
{
    [Required]
    [DataType(DataType.Text)]
    [Display(Name = "Stone")]
    public Nullable<short> Stone { get; set; }

    [Required]
    [DataType(DataType.Text)]
    [Display(Name = "Pound")]
    public Nullable<short> Pound { get; set; }
}

ただし、これらは異なる目的を持つ2つの個別のモデルであるため、次のコードを使用して、最終的にAccountControllerに正しくポストされ、データベースにレコードを追加するIEnumerableリストとフォーム要素のセットを含む単一のモデルに組み合わせるにはどうすればよいですか。

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult RecordCard(Weight Model)
{
    if (ModelState.IsValid)
    {
        using (WebApplication1Entities db = new WebApplication1Entities())
        {
            Weight weight = new Weight();
            weight.UserId = User.Identity.GetUserId();
            weight.Stone = Model.Stone;
            weight.Pound = Model.Pound;
            weight.Date = System.DateTime.Now;

            db.Weights.Add(Model);
            db.SaveChanges();
        }
    }
    return View(Model);
}

以下に重量クラスを含めました:

public partial class Weight
{
    public int Id { get; set; }
    public string UserId { get; set; }
    public Nullable<short> Stone { get; set; }
    public Nullable<short> Pound { get; set; }
    public Nullable<System.DateTime> Date { get; set; }
}

また、ここには、WeightテーブルをWeightsとして宣言するWebApplication1Entitiesクラスがあります。

public partial class WebApplication1Entities : DbContext
{
    public WebApplication1Entities()
        : base("name=WebApplication1Entities")
    {
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        throw new UnintentionalCodeFirstException();
    }

    public virtual DbSet<Weight> Weights { get; set; }
}

何を修正する必要があるのか​​、また、どのような方法で読み、従い、実装しようとしても、何か不足しているように見えるのか説明してください。

どんな助けでも大歓迎です:-)

9
iggyweb

私は前にこれに取り組みました、エレガントソリューションにたどり着くことができます。

最初に、送信するメインクラスと、最終的にviewに送信するためにそれらを格納する「ホルダー」クラスをセットアップする必要があります。
おそらくご存知のとおり、これはviewに複数のモデルを送信できないためです。

public class WebsiteTheme
{
    public string Color { get;set; }
    public string Title { get;set; }

    public WebsiteTheme() {
         Color = "blue";
         Title = "test website";
    }
}

public class User
{
    public string Name { get;set; }
    public string Gender { get;set; }

    public User() {
         Name = "Anonymous";
         Gender = "Unspecified";
    }
}

public class ToPage
{
    public WebsiteTheme WebsiteTheme{ get; set; }
    public User User { get; set; }

    public ToPage() {
         websiteTheme = new WebsiteTheme();
         user = new User();
    }
}

これにより、任意の量のクラスをページに送信できます。

次に、コントローラーで、これらのクラスを設定します。必ず最初にそれらをすべて初期化してから、移植されたクラスをホルダークラスに設定してください。

WebsiteTheme websiteTheme = new WebsiteTheme();
websiteTheme.Color = "orange";

User user = new User();
user.Name = "Darren";

ToPage toPage = new ToPage();
toPage.User = user;
toPage.WebsiteTheme = websiteTheme;

return View(toPage);

あなたの見解では、あなたは好きな方法でそれらを呼び出すでしょう。ただし、必ずHolderModel.SpecifiedModelすべての場合。

@model WebApplication1.Models.ToPage

@Html.DisplayFor(model => model.User.Name)
8
TheGeekZn

これは、ここでViewModelを使用する良い例だと思います。私は何かを提案します-

2つのクラスの構成でViewModelを作成します

public class AddWeightModel
{
    [Required]
    [DataType(DataType.Text)]
    [Display(Name = "Stone")]
    public Nullable<short> Stone { get; set; }

    [Required]
    [DataType(DataType.Text)]
    [Display(Name = "Pound")]
    public Nullable<short> Pound { get; set; }
}
....
public partial class Weight
{
    public int Id { get; set; }
    public string UserId { get; set; }
    public Nullable<short> Stone { get; set; }
    public Nullable<short> Pound { get; set; }
    public Nullable<System.DateTime> Date { get; set; }
}
.....
public class WeightViewModel
{
    public IList<AddWeightModel> AddWeightModel { get; set; }
    public Weight Weight { get; set; }
}

次に、ビューモデルを受け入れるようにビューを変更します-

@model WeightViewModel

最後に、変更に対処するためにコントローラーを変更します-

public ActionResult RecordCard()
    {
        var UserId = User.Identity.GetUserId();
        var weightModel = from m in db.Weights where m.UserId == UserId select m;
        var viewModel = new WeightViewModel
        {
            Weight = weightModel,
            AddWeightModel = new List<AddWeightModel>(){}
        };
        return View(viewModel);
    }

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult RecordCard(WeightViewModel viewModel)
{
    Weight Model = viewModel.Weight;
    if (ModelState.IsValid)
    {
        using (WebApplication1Entities db = new WebApplication1Entities())
        {
            Weight weight = new Weight();
            weight.UserId = User.Identity.GetUserId();
            weight.Stone = Model.Stone;
            weight.Pound = Model.Pound;
            weight.Date = System.DateTime.Now;

            db.Weights.Add(Model);
            db.SaveChanges();
        }
    }
    return RedirectToAction("RecordCard");
}
13
brainless coder

私はこのような複合モデルをしました:

public class CompoundModel 
{
    public SearchModel SearchModel { get; set; }
    public QueryResultRow ResultModel { get; set; }
}
public class QueryResultRow
{
    [DisplayName("Id")]
    public long id { get; set; }
    [DisplayName("Importdatum")]
    public System.DateTime importdate { get; set; }
    [DisplayName("Mandant")]
    public int indexBMClient { get; set; }
}

public class SearchModel 
{
    [Required]
    [DataType(DataType.Date)]
    [Display(Name = "Zeitraum von")]
    public DateTime dateFrom { get; set; }
    [Display(Name = "Terminal-ID")]
    public string tid { get; set; }
    [Display(Name = "Belegnummer")]
    public string receiptnumber { get; set; }
}

ビューのヘッダーで:

@model MyProject_aspmvc.Models.CompoundModel

そして、次のように、SearchModelからデータアクセスを取得します。

model => model.SearchModel.tid

resultModelからのデータアクセス、たとえば:

model => model.ResultModel.importdate 
1
Uwe Köhler