Сложные типы, связанные с моделью, не должны быть абстрактными или значениями и должны иметь конструктор без параметров - PullRequest
0 голосов
/ 17 января 2019

У меня следующая проблема, я создал приложение для добавления категорий игр и самих игр в базу данных. Я создал отношения и, к сожалению, когда я добавляю в базу данных, я получаю сообщение об ошибке.

Сложные типы, связанные с моделью, не должны быть абстрактными или значениями и должны иметь конструктор без параметров.

Категория игры Модель

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);
        }
    }
}

Понятия не имею, что не так.

Мой экран ошибок

enter image description here

Ответы [ 3 ]

0 голосов
/ 29 апреля 2019

вам нужно добавить [FromBody] к параметру, чтобы ядро ​​asp.net знало, как связать модель.

[HttpPost]
public IActionResult Add([FromBody] AddGameViewModel addGameViewModel)
0 голосов
/ 29 июня 2019

На момент написания этой статьи я столкнулся с этой проблемой в контроллере Asp.NET Core 2.2, где тип был введен в один из методов. Перемещение типа в конструктор контроллера обошло его. Так как это было неприемлемо, мы в конечном итоге реорганизовали класс-нарушитель из Контроллера в слой обработки, где синглтоны уже широко используются. Добавление еще одного к этому моменту прояснило нашу проблему.

Обратите внимание, что это контейнер OOB IoC, встроенный в Asp.Net Core. Другие поставщики IoC могут лучше обрабатывать инъекционные свойства методов.

Ламар может быть альтернативой.

Использование связывателя модели также могло бы сработать, поскольку связыватель мог бы использовать инъекцию одиночного и / или вспомогательного конструктора более аккуратно.

0 голосов
/ 17 января 2019

Не удалось создать экземпляр отношения .ViewModels.AddGameViewModel. Сложные типы, связанные с моделью, не должны быть абстрактными или значениями и должны иметь конструктор без параметров.

Давайте попробуем устранить эту ошибку.

Не удалось создать экземпляр отношения .ViewModels.AddGameViewModel.

Довольно очевидно: компоненты привязки к модели пытаются создать экземпляр вашего типа, но не удалось.

Связанные с моделью сложные типы

«Привязка к модели» означает, что они связаны конвейером ASP.NET. «сложные типы» - это в основном любые типы, которые не являются «базовыми», как string или int. Ваши классы моделей являются сложными типами.

не должно быть абстрактным

Система привязки к модели захочет иметь возможность создавать экземпляры класса, поэтому она не может быть абстрактной; это должно быть конкретным. Все показанные вами типы являются конкретными, поэтому это не проблема.

или типы значений

Вы не можете использовать struct типы с привязкой к модели; это только одно из его ограничений. К счастью, все ваши типы - это классы, поэтому вы можете игнорировать это.

и должен иметь конструктор без параметров.

ASP.NET не знает, как передавать параметры конструкторам моделей. Он может делать только эквивалент new T(), поэтому все типы вашей модели должны определять конструктор с нулевыми параметрами. Это причина, по которой вы видите ошибку; Ваш AddGameViewModel класс определяет только этот конструктор:

public AddGameViewModel(IEnumerable<GameCategory> categories)

Одна из особенностей языка C # заключается в том, что когда вы не указываете конструктор вручную, он добавляет для вас конструктор по умолчанию. Когда вы определяете конструктор в своем коде, этот конструктор по умолчанию не добавляется.

Во всех других ваших моделях вы не определяете никаких конструкторов, поэтому компилятор добавляет для вас компилятор по умолчанию. В случае AddGameViewModel вы добавили конструктор, поэтому для решения проблемы вы также должны добавить конструктор по умолчанию:

public AddGameViewModel()
{
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...