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.
Now have this working. Moved the property from the Book class to the AuthorViewModel class. Now Looks like the below.
Book Model:
Author Model:
ViewModel:
Changed Create view to:
Change your View at the top from @model
SimpleDropDownList.Models.Book
to @modelSimpleDropDownList.Models.AuthorViewModel