ASP.Net Core 3.1 MVC - 带有对象列表的多选

MJD*_*ing 6 c# razor asp.net-core

所以,基本上目标是:

用户从选择列表中为一本书(流派)选择多个“类别”。一些例子是:

  • 动作与冒险
  • 经典
  • 漫画书或图画小说

用户选择 1 个或多个(如此多个)后,他们会将书籍保存到数据库中。

就功能而言,当我处理单一类型(该类型被保存为单个字符串)时,一切都运行良好,但我需要支持多种类型。

我做的第一件事就是简单地将string Categoryto更改为List<string> Categories,但这导致了此处看到的错误:StackOverflow 问题,该问题已解决 我尝试了“TuPack”提供的解决方案,该错误消失了......但它导致了一个全新的问题问题。

您已经了解了我现在的情况:为了从我的 中获得任何结果<select></select> ,我必须这样做:

<select asp-for="CategoryIds[0].CategoryId" asp-items="ViewBag.Language"
        class="form-control" multiple="multiple">
   <option value="">Please choose book language</option>                    
</select>
Run Code Online (Sandbox Code Playgroud)

这当然有效......用于获取用户选择的第一个类别。仅此而已。

至于到目前为止的代码,从相关性角度来看......我将切断与数据库相关的内容,因为问题早在那时就发生了:

控制器:

public async Task<ViewResult> AddNewBookAsync(bool isSuccess = false, int bookId = 0)
        {
            var model = new BookModel();
            
            ViewBag.Language = new SelectList(await _languageRepository.GetLanguages(), "Id", "Name");

            ViewBag.IsSucess = isSuccess;
            ViewBag.BookId = bookId;            
            return View(model);
        }

        [HttpPost]
        public async Task<IActionResult> AddNewBook(BookModel bookModel)
        {


            if (ModelState.IsValid)
            {
                int id = await _bookRepository.AddNewBook(bookModel);
                if(id > 0)
                {
                    return RedirectToAction(nameof(AddNewBook), new { isSuccess = true, bookId = true });
                }
            }



            ViewBag.Language = new SelectList(await _languageRepository.GetLanguages(), "Id", "Name");
            return View();
        }
Run Code Online (Sandbox Code Playgroud)

书籍型号:

public class BookModel
    {
        public int Id { get; set; }
        [StringLength(100, MinimumLength = 5)]
        [Required(ErrorMessage ="Please enter the title of your book")]
        public string Title { get; set; }
        [Required(ErrorMessage = "Please enter the author's name")]
        public string Author { get; set; }
        [StringLength(500)]
        public string Description { get; set; }
        
        [Required(ErrorMessage = "Please choose the language of your book")]
        public string Language { get; set; }
        [Display(Name = "Genre")]
        public List<Categories> CategoryIds { get; set; } = new List<Categories>();

        [Required(ErrorMessage = "Please enter the total pages")]
        [Display(Name = "Total pages of book")]
        public int? TotalPages  { get; set; }
    }
Run Code Online (Sandbox Code Playgroud)

我之前已经展示过相关的Html代码,所以不再发布。

视觉效果:输入示例: 输入示例 电流输出: 电流输出

类别 ID 1 是“动作与冒险”。

顺便说一句,我确信这很容易分辨,但这只是一个“练习项目”。我不想在不知道自己在做什么的情况下对我正在从事的主要项目做出重大改变。

更新:使用CategoryIds[0].CategoryId与以前完全相同的值更改并运行它后,我得到: 0 个对象结果

Mic*_*ang 6

更新

在此输入图像描述

我曾经添加一个IList<SelectListItem>属性来Book建模并在属性中存储多个类别CategoryIds。这对我有用。

控制器代码

    public IList<SelectListItem> GetCategories()
    {
        var categories = new List<Category>
        {
            new Category {Id = 1, CategoryName = "Action and Adventure"},
            new Category {Id = 2, CategoryName = "Classics"},
            new Category {Id = 3, CategoryName = "Comic Book or Graphic Novel"},
        };  // here you can load categories from DB, this is only for test
        


        var categoryListItem = categories
       .Select(x => new SelectListItem { Text = x.CategoryName, Value = x.Id.ToString() })
       .ToList();

        return categoryListItem;
    }


    [Route("/books/add")]
    public IActionResult _AddNewBooks()
    {
        var model = new BookModel { CategoryList = GetCategories() };

        return View(model);
    }


    [Route("/books/addnewbook")]
    [HttpPost]
    public IActionResult AddNewBook(BookModel model)
    {
        if (ModelState.IsValid)
        {
            //int id = await _bookRepository.AddNewBook(bookModel);
            //if (id > 0)
            //{
            //    return RedirectToAction(nameof(AddNewBook), new { isSuccess = true, bookId = true });
            //}
        }

        //ViewBag.Language = new SelectList(await _languageRepository.GetLanguages(), "Id", "Name");
        model.CategoryList = GetCategories();

        return View();

    }
Run Code Online (Sandbox Code Playgroud)

型号代号

public class BookModel
{
    public int Id { get; set; }

    public string Title { get; set; }

    public IList<SelectListItem> CategoryList { get; set; }

    [Required(ErrorMessage = "Please select at last 1 Category")]
    public List<int> CategoryIds { get; set; }


    public BookModel(){
        CategoryList = new List<SelectListItem>();
    }
}


public class Category
{
    public int Id { get; set; }
    public string CategoryName { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

视图代码

<select asp-for="CategoryIds" asp-items="Model.CategoryList" 
           placeholder="Select Categories" 
           onchange="console.log($(this).children(':selected').length)" 
           class="search-box form-control">
</select>
Run Code Online (Sandbox Code Playgroud)



@MJDeveloping,

1>您正在使用ViewBag.Language 的项目 Category。我建议你回到Categories视图。

2> asp-for应该是CategoryIds

<select asp-for="CategoryIds" asp-items="ViewBag.Language"
        class="form-control" multiple="multiple">
   <option value="">Please choose book language</option>                    
</select>
Run Code Online (Sandbox Code Playgroud)