2017-10-16 20 views
1

私はカスタムモデルバインダーasp.netコア2を構築する問題があります。 私はこれを読んでTutorialしかし、それは私が必要なものではありません。asp.netコア2複雑なモデルのカスタムモデルバインダー

私は、ビルドの例を持っていると私はそのような単純なPersonクラス持っgithub

に置く:私は新しい人を追加すると

public class Person 
{ 
    public int ID { get; set; } 

    [Required] 
    public string Firstname { get; set; } 

    [Required] 
    public string Surename { get; set; } 

    [Required] 
    [DisplayFormat(DataFormatString = "{0:dd.MMM.yyyy}")] 
    public DateTime DateOfBirth {get;set;} 

    [Required] 
    public Country Country { get; set; } 
} 

public class Country 
{ 
    public int ID { get; set; } 

    public string Name { get; set; } 

    public string Code { get; set; } 
} 

が、私はHTMLのselectタグで国を選択することができますが。しかし、selectタグの値は国のIDです。私はバインダーをデータベースで検索し、適切な国をモデルに追加します。

コントローラにメソッドを作成するには、次のようになります

[HttpPost] 
    [ValidateAntiForgeryToken] 
    public async Task<IActionResult> Create([Bind("ID,Firstname,Surename,DateOfBirth")] Person person, int Country) 
    { 
     ViewData["Countries"] = _context.Countries.ToList(); 

     if (ModelState.IsValid) 
     { 
      _context.Add(person); 
      await _context.SaveChangesAsync(); 
      return RedirectToAction(nameof(Index)); 
     } 
     return View(person); 
    } 

私はまた、データをバインドするIModelBinderを実装:

public class PersonEntityBinder : IModelBinder 
{ 
    public Task BindModelAsync(ModelBindingContext bindingContext) 
    { 
     if (bindingContext == null) 
     { 
      throw new ArgumentNullException(nameof(bindingContext)); 
     } 

     // here goes the fun 

     // looking for the countryId in the bindingContext 

     // binding everything else except the CountryID 

     // search the Country by countryID and put it to the model 


     return Task.CompletedTask; 
    } 
} 

質問は、私が書いたように私はこれを行うことができる方法であり、バインダーのコメントに? 誰かがアイデアやベストプラクティスのソリューションですか?

についてChris

+0

あなたは、基本的なアクションのCOMPLEXE何かをしたいのはなぜ?プロパティを追加するだけです。public int CountryId {get;あなたのモデルに国のIDを設定してください.Entityフレームワークはあなたに残ります – OrcusZ

答えて

2

まず、これはカスタムモデルバインダーの悪い使用です。コントローラーの責任であるので、データ・アクセスはコントローラー内で起こるはずです。次に、don't use [Bind]。まじめにね。ただしないでください。それはひどいです、そしてそれは子猫を殺します。アクションこの代わりに([Bind]のためのより多くの必要性を)受け入れていない、そして、

public class PersonViewModel 
{ 
    public string FirstName { get; set; } 
    public string Surname { get; set; } 
    public DateTime DateOfBirth { get; set; } 
    public int CountryID { get; set; } 
} 

ようなビューモデルを作成します

public async Task<IActionResult> Create(PersonViewModel model) 

を次に、あなたの行動の内側に、掲載さ値をマッピングPersonの新しいインスタンスに変更し、Countryプロパティをデータベースから探して入力します。

var person = new Person 
{ 
    FirstName = model.FirstName, 
    Surname = model.Surname, 
    DateOfBirth = model.DateOfBirth, 
    Country = db.Countries.Find(model.CountryID) 
} 

その後、通常通り、personを保存します。

+0

これは私がいくつかのJavaフレームワークから知っている方法で、私の意見では最良の方法です。私はVisual Studioから足場コードを信じることができないようです。ありがとうございます –

+0

さて、足場はそんなにしかできません。人々が間違って行くところは、足場が始まりと終わりの場所であると仮定することです。ポイントはあなたに出発点を与えることです。コードをカスタマイズして独自のものにすることを前提としています。 –

関連する問題