模型绑定的复杂类型不能为抽象或值类型,并且必须具有无参数构造函数 [英] Model bound complex types must not be abstract or value types and must have a parameterless constructor

查看:184
本文介绍了模型绑定的复杂类型不能为抽象或值类型,并且必须具有无参数构造函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到以下问题,我创建了一个应用程序,将游戏类别和游戏本身添加到数据库中。我创建了一个关系,但是不幸的是,当我添加到数据库中时,我得到一个错误。

I have the following problem, I created an application to add game categories and the games themselves to the database. I created a relationship and unfortunately when I add to the database I get an error.


模型绑定的复杂类型一定不能是抽象或值类型并且
必须具有无参数构造函数。

Model bound complex types must not be abstract or value types and must have a parameterless constructor.

游戏类别模型

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

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

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

and last is 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的实例。绑定了模型的复杂类型不能是抽象或值类型,并且必须具有无参数的构造函数。

Could not create an instance of relationship.ViewModels.AddGameViewModel. Model bound complex types must not be abstract or value types and must have a parameterless constructor.

让我们尝试消除此错误。 / p>

Let's try and break this error down.


无法创建一个Relationship.ViewModels.AddGameViewModel实例。

Could not create an instance of relationship.ViewModels.AddGameViewModel.

不言自明:模型绑定组件正在尝试创建您类型的实例,但失败了。

Pretty self-explanatory: the model-binding components are trying to create an instance of your type, but failed.


绑定模型的复杂类型

Model bound complex types

绑定模型是指它们被ASP.NET管道绑定。 复杂类型基本上是不是基本的任何类型,例如 string int 。您的模型类是复杂的类型。

"Model bound" refers to that they're being bound by the ASP.NET pipeline. "complex types" are basically any types which aren't "basic" like string or int. Your model classes are complex types.


一定不能抽象

must not be abstract

模型绑定系统将希望能够创建该类的实例,因此它不能是抽象的。它必须是具体的。您显示的所有类型都是具体的,因此这不是问题。

The model-binding system is going to want to be able to create instances of the class, so it cannot be abstract; it must be concrete. All of the types you've show are concrete so this isn't the problem.


或值类型

or value types

不能将 struct 类型与模型绑定一起使用;这只是其局限性之一。幸运的是您的类型都是类,所以您可以忽略它。

You can't use struct types with model-binding; it's just one of its limitations. Fortunately your types are all classes, so you can ignore this.


,并且必须具有无参数构造函数。

and must have a parameterless constructor.

ASP.NET不知道如何向模型构造函数提供参数。它只能执行 new T()的等效项,因此所有模型类型都必须定义一个具有零参数的构造函数。这就是您看到错误的原因;您的 AddGameViewModel 类仅定义此构造函数:

ASP.NET doesn't know how to supply parameters to model constructors. It can only do the equivalent of new T(), so all your model types must define a constructor which has zero parameters. This is the reason you're seeing the error; your AddGameViewModel class only defines this constructor:

public AddGameViewModel(IEnumerable<GameCategory> categories)

C#语言功能之一是当您不手动指定构造函数时,它会为您添加一个默认值。在代码中定义构造函数时,不会添加此默认构造函数。

One of the C# language features is that when you don't specify a constructor manually, it adds a default one for you. When you define a constructor in your code, this default constructor is not added.

在所有其他模型中,您没有定义任何构造函数,因此编译器将添加默认的一个给你。对于 AddGameViewModel ,您已经添加了一个构造函数,因此,要解决该问题,还必须添加默认的构造函数:

In all of your other models, you aren't defining any constructors so the compiler is adding the default one for you. In the case of AddGameViewModel you have added a constructor, so to fix the problem you must also add the default constructor:

public AddGameViewModel()
{
}

这篇关于模型绑定的复杂类型不能为抽象或值类型,并且必须具有无参数构造函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆