Catarina
Catarina

Reputation: 1

MVC Error - An unhandled exception occurred while processing the request. InvalidOperationException: The model passed

I'm having the following error when I'm trying to create a product:

An unhandled exception occurred while processing the request. InvalidOperationException: The model item passed into the ViewDataDictionary is of type 'Library.Models.Wine.Product', but this ViewDataDictionary instance requires a model item of type 'Library.ViewModels.ProductViewModel'.

Where is the problem in my code? Does anyone know?

Here is the code:

My Product Service:

public async Task InsertAsync(Product obj)
{
    _context.Add(obj);
    await _context.SaveChangesAsync();
}

My Product ViewModel:

public Product products { get; set; }
public virtual ICollection<WineBrand> wine_brands { get; set; }
public virtual ICollection<Harvest> harvests { get; set; }

My Product Controller:

        private readonly ProductService _productService;
        private readonly WineBrandService _wineBrandService;
        private readonly HarvestService _harvestService;

        public ProductsController( 
            ProductService productService, 
            WineBrandService wineBrandService, 
            HarvestService harvestService)
        {
            _productService = productService;
            _wineBrandService = wineBrandService;
            _harvestService = harvestService;

        }

    public async Task<IActionResult> Create()
    {
        var wine = await _wineBrandService.FindAllAsync();
        var year = await _harvestService.FindAllAsync();

        var viewmodel = new ProductViewModel 
        { 
            wine_brands = wine,
            harvests = year

        };

        return View(viewmodel);
    }

    [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> Create(Product product)
    {
        if (!ModelState.IsValid)
        {
            return View(product);
        }

        await _productService.InsertAsync(product);
        return RedirectToAction(nameof(Index));
    }

My Product Create View:

   @model Library.ViewModels.ProductViewModel

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

<h1>Create</h1>

<h4>Employee</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="products.Name" class="control-label"></label>
                <input asp-for="products.Name" class="form-control" />
                <span asp-validation-for="products.Name" class="text-danger"></span>
            </div>

            <div class="form-group">
                <label asp-for="products.Price" class="control-label"></label>
                <input asp-for="products.Price" class="form-control" />
                <span asp-validation-for="products.Price" class="text-danger"></span>
            </div>

            <div class="form-group">
                <label asp-for="products.WineBrandId" class="control-label"></label>
                <select asp-for="products.WineBrandId" asp-items="@(new SelectList(Model.wine_brands, "Id", "Name"))" class="form-control"></select>
                <span asp-validation-for="products.Brand" class="text-danger"></span>
            </div>

            <div class="form-group">
                <label asp-for="products.HarvestId" class="control-label"></label>
                <select asp-for="products.HarvestId" asp-items="@(new SelectList(Model.harvests, "Id", "Year"))" class="form-control"></select>
                <span asp-validation-for="products.Harvest" class="text-danger"></span>
            </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");}
}

Upvotes: 0

Views: 4914

Answers (3)

EmilioSteneg
EmilioSteneg

Reputation: 1

I had the same problem with all projects and it does not work any of solutions that you find out in forums. It should be an issue in the configuration of Visual Studio, however I did not find out where the problem is, just this solution.

My solution is to run dotnet watch run from the console. Stop it and then run from Visual Studio 22 as debug without building it again. It will work.

Upvotes: 0

MatR
MatR

Reputation: 305

The problem is that you return Product instead of ProductViewModel. Updated Post method below

    [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> Create(ProductViewModel model)
    {
        if (!ModelState.IsValid)
        {
            model.wine_brands = await _wineBrandService.FindAllAsync();
            model.harvests = await _harvestService.FindAllAsync();
            return View(model);
        }
        var product = new Product(){
              // assign properties form model to new product here
        };
        await _productService.InsertAsync(product);
        return RedirectToAction(nameof(Index));
    }

Upvotes: 0

DavSin
DavSin

Reputation: 134

You applied [ValidateAntiForgeryToken] token in your controller but not set it into view.

<form asp-action="Create">
  @Html.AntiForgeryToken()
...
...
...

Upvotes: 0

Related Questions