skip to Main Content

What am I doing?
I am trying using two modal in one view.

What’s the problem?
When run give this error:

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

Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary.EnsureCompatible(object value)

Part of "PersonController.cs":

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.EntityFrameworkCore;
using ProgramaEstagio.Data;
using ProgramaEstagio.Models;

namespace ProgramaEstagio.Controllers
{
    public class PersonController : Controller
    {
        private readonly ApplicationDbContext _context;

        public PersonController(ApplicationDbContext context)
        {
            _context = context;
        }

        // GET: Person
        public async Task<IActionResult> Index()
        {
            return View(await _context.Person.ToListAsync());
        }
        // GET: Person/Edit/5
        public async Task<IActionResult> Edit(int? id)
        {
            if (id == null)
            {
                return NotFound();
            }

            var person = await _context.Person.FindAsync(id);
            if (person == null)
            {
                return NotFound();
            }
            return View(person);
        }

        // POST: Person/Edit/5
        // To protect from overposting attacks, enable the specific properties you want to bind to.
        // For more details, see http://go.microsoft.com/fwlink/?LinkId=317598.
        [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> Edit(int id, [Bind("ID,FullName,BirthDate,sex")] Person person)
        {
            if (id != person.ID)
            {
                return NotFound();
            }

            if (ModelState.IsValid)
            {
                try
                {
                    _context.Update(person);
                    await _context.SaveChangesAsync();
                }
                catch (DbUpdateConcurrencyException)
                {
                    if (!PersonExists(person.ID))
                    {
                        return NotFound();
                    }
                    else
                    {
                        throw;
                    }
                }
                return RedirectToAction(nameof(Index));
            }
            return View(person);
        }

RegisterViewModel.cs:

namespace ProgramaEstagio.Models
{
    public class RegisterViewModel
    {
        public Person Person { get; set; }
        public Address Address { get; set; }
    }
}

Edit.cshtml:

@model ProgramaEstagio.Models.RegisterViewModel

@{
    ViewData["Title"] = "Edit";
}

<h1>Edit</h1>

<h4>Person</h4>
<hr />
<div class="row">
    <div class="col-md-4">
        <form asp-action="Edit">
            <div asp-validation-summary="ModelOnly" class="text-danger"></div>
            <input type="hidden" asp-for="Person.ID" />
            <div class="form-group">
                <label asp-for="Person.FullName" class="control-label"></label>
                <input asp-for="Person.FullName" class="form-control" />
                <span asp-validation-for="Person.FullName" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Person.BirthDate" class="control-label"></label>
                <input asp-for="Person.BirthDate" class="form-control" />
                <span asp-validation-for="Person.BirthDate" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Person.sex" class="control-label"></label>
                <input asp-for="Person.sex" class="form-control" />
                <span asp-validation-for="Person.sex" class="text-danger"></span>
            </div>

            <h4>Address</h4>
            <div asp-validation-summary="ModelOnly" class="text-danger"></div>
            <input type="hidden" asp-for="Address.ID" />
            <div class="form-group">
                <label asp-for="Address.Country" class="control-label"></label>
                <input asp-for="Address.Country" class="form-control" />
                <span asp-validation-for="Address.Country" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Address.Complement" class="control-label"></label>
                <input asp-for="Address.Complement" class="form-control" />
                <span asp-validation-for="Address.Complement" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Address.Distric" class="control-label"></label>
                <input asp-for="Address.Distric" class="form-control" />
                <span asp-validation-for="Address.Distric" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Address.City" class="control-label"></label>
                <input asp-for="Address.City" class="form-control" />
                <span asp-validation-for="Address.City" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Address.State" class="control-label"></label>
                <input asp-for="Address.State" class="form-control" />
                <span asp-validation-for="Address.State" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Address.PersonID" class="control-label"></label>
                <select asp-for="Address.PersonID" class="form-control" asp-items="ViewBag.PersonID"></select>
                <span asp-validation-for="Address.PersonID" class="text-danger"></span>
            </div>

            <div class="form-group">
                <input type="submit" value="Save" class="btn btn-primary" />
            </div>
        </form>
    </div>
</div>

<div>
    <a asp-action="Index">Back to List</a>
</div>

@section Scripts {
    @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}

What I have to do? please help me. If need more information, ask please. And sorry for any error orthography and grammar I am studing English.
Project Link: https://github.com/vitorhugo1207/Sys-Vacina/tree/EditPagePersonAdress

Edit:
AddressController.cs:

        // GET: Addresse/Edit/5
        public async Task<IActionResult> Edit(int? id)
        {
            RegisterViewModel register = new RegisterViewModel();
            if (id == null)
            {
                return NotFound();
            }

            var address = await _context.Address.FindAsync(id);
            if (address == null)
            {
                return NotFound();
            }
            ViewData["PersonID"] = new SelectList(_context.Person, "ID", "FullName", address.PersonID);
            register.Address = address;
            return View(register);
        }

        // POST: Addresse/Edit/5
        // To protect from overposting attacks, enable the specific properties you want to bind to.
        // For more details, see http://go.microsoft.com/fwlink/?LinkId=317598.
        [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> Edit(int id, [Bind("ID,Country,Complement,Distric,City,State,PersonID")] Address address)
        {
            if (id != address.ID)
            {
                return NotFound();
            }

            if (ModelState.IsValid)
            {
                try
                {
                    _context.Update(address);
                    await _context.SaveChangesAsync();
                }
                catch (DbUpdateConcurrencyException)
                {
                    if (!AddressExists(address.ID))
                    {
                        return NotFound();
                    }
                    else
                    {
                        throw;
                    }
                }
                return RedirectToAction(nameof(Index));
            }
            ViewData["PersonID"] = new SelectList(_context.Person, "ID", "FullName", address.PersonID);
            return View(address);
        }

2

Answers


  1. It is happening on this line: return View(person);. You are sending a Model of type Person but you need to send a Model of RegisterViewModel. You need to send the correct Model to your View:

        public async Task<IActionResult> Edit(int? id)
        {
            RegisterViewModel register = new RegisterViewModel();
            if (id == null)
            {
                return NotFound();
            }
    
            var person = await _context.Person.FindAsync(id);
            if (person == null)
            {
                return NotFound();
            }
            register.Person = person;
            var address = await _context.Address.FindAsync(id);
            if (address == null)
            {
                return NotFound();
            }
            register.Address = address;
            return View(register);
        }
    
    Login or Signup to reply.
  2. You essentially made a promise to C# that you would send a model of type RegisterViewModel, when you wrote this:

    @model ProgramaEstagio.Models.RegisterViewModel
    

    But then you actually sent a Person instead:

    var person = await _context.Person.FindAsync(id);
    ...
    return View(person);
    

    It doesn’t really matter what these two things are, so long as they agree; if you upgrade/change the type in one place (like the cshtml), you have to change it everywhere else (like the controller View(..) calls) to ensure they remain in agreement with each other

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search