简体   繁体   中英

Error when Razor page opens and have a related drop down list

I'm attempting to create a form (Books) with a simple drop down list displaying fields from a related table (Authors).

Book Model:

namespace SimpleDropDownList.Models
{
    public class Book
    {
        [Key]
        public int BookID { get; set; }
        [StringLength(255)]
        [Display(Name = "Book Title")]
        public string Title { get; set; }
        public int AuthorID { get; set; }
        public Author Author { get; set; }
        public AuthorViewModel AuthorViewModel { get; set; }
    }
}

Author Model:

namespace SimpleDropDownList.Models
{
    public class Author
    {
        [Key]
        public int AuthorID { get; set; }
        [Display(Name = "First Name")]
        [StringLength(50)]
        public string FirstName { get; set; }
        [Display(Name = "Last Name")]
        [StringLength(50)]
        public string LastName { get; set; }
        public ICollection<Book> Books { get; set; } = new List<Book>();
    }
}

ViewModel:

namespace SimpleDropDownList.Models
{
    [NotMapped]
    public class AuthorViewModel
    {
        //Property to hold the list of authors in the GET
        public IEnumerable<SelectListItem> AuthorOptions { get; set; }

        //Property to bind the selected author used in the POST
        public List<int> SelectedAuthorIds { get; set; }
    }
}

Create() method on the BooksController:

public IActionResult Create()
            {
                //ViewData["AuthorID"] = new SelectList(_context.Set<Author>(), "AuthorID", "AuthorID");
                AuthorViewModel vm = new AuthorViewModel();
                vm.AuthorOptions = _context.Book.Select(x => new SelectListItem()
                { Value = x.AuthorID.ToString(), Text = x.Author.LastName }).ToList();
            return View(vm);
            }

Create View:

  @model SimpleDropDownList.Models.Book @{ ViewData["Title"] = "Create"; } <h1>Create</h1> <h4>Book</h4> <hr /> <div class="row"> <div class="col-md-4"> <form asp-action="Create"> <div asp-validation-summary="ModelOnly" class="text-danger"></div> <div class="form-group"> <label asp-for="Title" class="control-label"></label> <input asp-for="Title" class="form-control" /> <span asp-validation-for="Title" class="text-danger"></span> </div> <div class="form-group"> <label asp-for="AuthorID" class="control-label"></label> @*<select asp-for="AuthorID" class ="form-control" asp-items="ViewBag.AuthorID"></select>*@ <select asp-for="@Model.AuthorViewModel.SelectedAuthorIds" asp-items="@Model.AuthorViewModel.AuthorOptions"></select> </div> <div class="form-group"> <input type="submit" value="Create" class="btn btn-primary" /> </div> </form> </div> </div> <div> <a asp-action="Index">Back to List</a> </div> @section Scripts { @{await Html.RenderPartialAsync("_ValidationScriptsPartial");} } Model: AuthorViewModel 

When the Create button is clicked the following error is generated.

An unhandled exception occurred while processing the request. InvalidOperationException: The model item passed into the ViewDataDictionary is of type 'SimpleDropDownList.Models.AuthorViewModel', but this ViewDataDictionary instance requires a model item of type 'SimpleDropDownList.Models.Book'.

My expectations are simple...open the create Book form and drop down list to display the author ID and last name.

将顶部的视图从@model SimpleDropDownList.Models.Book更改为@model SimpleDropDownList.Models.AuthorViewModel

Now have this working. Moved the property from the Book class to the AuthorViewModel class. Now Looks like the below.

Book Model:

namespace SimpleDropDownList.Models
{
    public class Book
    {
        [Key]
        public int BookID { get; set; }
        [StringLength(255)]
        [Display(Name = "Book Title")]
        public string Title { get; set; }
        public int AuthorID { get; set; }
        public Author Author { get; set; }
        // Removed this link and added property to AuthorViewModel class
        // public AuthorViewModel AuthorViewModel { get; set; }
    }
}

Author Model:

namespace SimpleDropDownList.Models
{
    public class Author
    {
        [Key]
        public int AuthorID { get; set; }
        [Display(Name = "First Name")]
        [StringLength(50)]
        public string FirstName { get; set; }
        [Display(Name = "Last Name")]
        [StringLength(50)]
        public string LastName { get; set; }
        public ICollection<Book> Books { get; set; } = new List<Book>();
    }
}

ViewModel:

namespace SimpleDropDownList.Models
    {
        [NotMapped]
        public class AuthorViewModel
        {
            //Property to hold the list of authors in the GET
            public IEnumerable<SelectListItem> AuthorOptions { get; set; }

            //Property to bind the selected author used in the POST
            public List<int> SelectedAuthorIds { get; set; }

            // Added this property to link back to Book class
            public Book Book { get; set; }
        }
    }

Changed Create view to:

public IActionResult Create()
{
    // The ViewData line auto created by the scaffolding process
    // ViewData["AuthorID"] = new SelectList(_context.Set<Author>(), "AuthorID", "AuthorID");

    AuthorViewModel vm = new AuthorViewModel();
    vm.AuthorOptions = _context.Book.Select(x => new SelectListItem()
    { Value = x.AuthorID.ToString(), Text = x.Author.LastName }).ToList();

    return View(vm);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM