次の問題があります。ゲームカテゴリとゲーム自体をデータベースに追加するアプリケーションを作成しました。リレーションシップを作成しましたが、残念ながらデータベースに追加するとエラーが発生します。
モデルにバインドされた複合型は、抽象型または値型であってはならず、パラメーターなしのコンストラクターを持っている必要があります。
ゲームカテゴリモデル
using System.Collections.Generic;
namespace relationship.Models
{
public class GameCategory
{
public int Id { get; set; }
public string Name { get; set; }
public ICollection<Game> Game { get; set; }
}
}
ゲームモデル
namespace relationship.Models
{
public class Game
{
public int GameId { get; set; }
public string Name { get; set; }
public GameCategory Category { get; set; }
public int CategoryId { get; set; }
}
}
ViewModel
using relationship.Models;
using System.ComponentModel.DataAnnotations;
using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc.Rendering;
namespace relationship.ViewModels
{
public class AddGameViewModel
{
[Required]
public string GameName { get; set; }
public int CategoryID { get; set; }
public List<SelectListItem> Categories { get; set; }
public AddGameViewModel(IEnumerable<GameCategory> categories)
{
Categories = new List<SelectListItem>();
foreach (var catData in categories)
{
Categories.Add(new SelectListItem { Text = catData.Name.ToString(), Value = catData.Id.ToString() });
}
return;
}
}
}
GameRepository
using System.Collections.Generic;
using System.Linq;
namespace relationship.Models
{
public class GameRepository : IGameRepository
{
private readonly AppDbContext appDbContext;
public GameRepository(AppDbContext dbContext)
{
appDbContext = dbContext;
}
public void AddGame(Game game)
{
appDbContext.Games.Add(game);
appDbContext.SaveChanges();
}
public IEnumerable<Game> Games()
{
return appDbContext.Games.ToList();
}
}
}
最後はGameControllerです
using Microsoft.AspNetCore.Mvc;
using relationship.Models;
using relationship.ViewModels;
namespace relationship.Controllers
{
public class GameController : Controller
{
private readonly IGameRepository gameRepository;
private readonly ICategoryRepository categoryRepository;
public GameController(IGameRepository gameRepo, ICategoryRepository catRepo)
{
gameRepository = gameRepo;
categoryRepository = catRepo;
}
public IActionResult Index()
{
return View();
}
[HttpGet]
public IActionResult Add()
{
var addGameViewModel = new AddGameViewModel(categoryRepository.GameCategory());
return View(addGameViewModel);
}
[HttpPost]
public IActionResult Add(AddGameViewModel addGameViewModel)
{
if (ModelState.IsValid)
{
GameCategory gameCategory = categoryRepository.GetDetails(addGameViewModel.CategoryID);
if(gameCategory == null)
{
return NotFound();
}
Game game = new Game
{
Name = addGameViewModel.GameName,
Category = gameCategory
};
gameRepository.AddGame(game);
return RedirectToAction("Index");
}
return View(addGameViewModel);
}
}
}
何が悪いのかわかりません。
エラー画面
Relationship.ViewModels.AddGameViewModelのインスタンスを作成できませんでした。モデルにバインドされた複合型は、抽象型または値型であってはならず、パラメーターなしのコンストラクターを持っている必要があります。
このエラーを分解してみましょう。
Relationship.ViewModels.AddGameViewModelのインスタンスを作成できませんでした。
かなり自明です。モデルバインディングコンポーネントは、タイプのインスタンスを作成しようとしていますが、失敗しました。
モデルにバインドされた複合型
「モデルバインド」とは、ASP.NETパイプラインによってバインドされていることを意味します。「複雑なタイプ」とは、基本的に、string
またはのような「基本」ではないタイプのことint
です。モデルクラスは複合型です。
抽象的であってはなりません
モデルバインディングシステムは、クラスのインスタンスを作成できるようにする必要があるため、抽象化することはできません。それは具体的でなければなりません。表示するタイプはすべて具体的であるため、これは問題ではありません。
または値型
struct
モデルバインディングで型を使用することはできません。それはその制限の1つにすぎません。幸い、タイプはすべてクラスなので、これは無視してかまいません。
パラメータのないコンストラクタが必要です。
ASP.NETは、モデルコンストラクターにパラメーターを提供する方法を知りません。と同等の処理しか実行できないnew T()
ため、すべてのモデルタイプで、パラメーターがゼロのコンストラクターを定義する必要があります。これがエラーが表示される理由です。AddGameViewModel
クラスはこのコンストラクターのみを定義します。
public AddGameViewModel(IEnumerable<GameCategory> categories)
C#言語の機能の1つは、コンストラクターを手動で指定しない場合、デフォルトのコンストラクターが追加されることです。コードでコンストラクターを定義する場合、このデフォルトのコンストラクターは追加されません。
他のすべてのモデルでは、コンストラクターを定義していないため、コンパイラーがデフォルトのコンストラクターを追加します。AddGameViewModel
コンストラクターを追加した場合、問題を修正するには、デフォルトのコンストラクターも追加する必要があります。
public AddGameViewModel()
{
}
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加