UPDATE INSERINDO NOVO ITEM EM VEZ DE ATUALIZAR

KELLY 28/08/2022 19:40:46
#500379
Olá pessoal!

Preciso de ajuda para identificar um problema no meu código, quando eu clico em atualizar produto, ele insere um novo com as informações que deveria ser aplicada ao produto que desejo atualizar.
Revisei todo o código e não encontrei o problema. Segue o meu código:


Services
namespace CleanArch.Application.Services
{
public class ProductService : IProductService
{
private IProductRepository _productRepository;
private readonly IMapper _mapper;
public ProductService(IMapper mapper, IProductRepository productRepository)
{
_productRepository = productRepository;
_mapper = mapper;
}
public void Add(ProductViewModel product)
{
var mapProduct = _mapper.Map<Product>(product);
_productRepository.Add(mapProduct);
}
public void Update(ProductViewModel product)
{
var mapProduct = _mapper.Map<Product>(product);
_productRepository.Update(mapProduct);
}
public void Remove(int? id)
{
var product = _productRepository.GetById(id).Result;
_productRepository.Remove(product);
}
public async Task<ProductViewModel> GetById(int? id)
{
var result = await _productRepository.GetById(id);
return _mapper.Map<ProductViewModel>(result);
}

public async Task<IEnumerable<ProductViewModel>> GetProdutcts()
{
var result = await _productRepository.GetProducts();
return _mapper.Map<IEnumerable<ProductViewModel>>(result);
}
}
}

Controllers
namespace CleanArch.MVC.Controllers
{
public class ProductsController : Controller
{
private readonly IProductService _productService;
public ProductsController(IProductService productService)
{
_productService = productService;
}

[HttpGet]
public async Task<IActionResult> Index()
{
var result = await _productService.GetProdutcts();
return View(result);
}

[HttpGet]
public IActionResult Create()
{
return View();
}

[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Create([Bind("Id, Name, Description, Price")] ProductViewModel product)
{
if (ModelState.IsValid)
{
_productService.Add(product);
return RedirectToAction(nameof(Index));
}
return View(product);
}

[HttpGet()]
public async Task<IActionResult> Edit(int? id)
{
if (id == null) return
NotFound();

var productVM = await _productService.GetById(id);

if (productVM == null) return
NotFound();

return View(productVM);
}

[HttpPost()]
public IActionResult Edit([Bind("Id, Name, Description, Price")] ProductViewModel productVM)
{
if (ModelState.IsValid)
{
try
{
_productService.Update(productVM);
}
catch (Exception)
{

throw;
}
return RedirectToAction(nameof(Index));
}
return View(productVM);
}

public async Task<IActionResult> Details(int? id)
{
if (id == null)
{
return NotFound();
}

var productVM = await _productService.GetById(id);
if (productVM == null)
{
return NotFound();
}

return View(productVM);
}

[HttpGet]
public async Task<IActionResult> Delete(int? id)
{
if (id == null)
return NotFound();

var productVM = await _productService.GetById(id);

if (productVM == null) return NotFound();

return View(productVM);
}

[HttpPost(), ActionName("Delete")]
public IActionResult DeleteConfirmed(int id)
{
_productService.Remove(id);

return RedirectToAction("Index");
}
}
}
KERPLUNK 29/08/2022 15:46:35
#500381
Resposta escolhida
Mostra o código do form
KELLY 29/08/2022 20:06:11
#500383
Oi Kerplunk!

Segue o código da View Index que chama a View Edit e também a ViewEdit completa.

View Index

@model IEnumerable<CleanArch.Application.ViewModels.ProductViewModel>

@{
ViewData["Title"] = "Products Management";
}

@*<style>
.modal-lg{
max-width: 80%;
}
</style>*@

<h1>Products</h1>

<hr/>

<div class="row">
<div class="col-md-12">
<div>
<div class="pull-left">
<a asp-action="Create" class="btn btn-primary">
<span title="New" class="fas fa-plus"></span> New
</a>
</div>
</div>
</div>
</div>
<table class="table">
<thead>
<tr>
<th>
@Html.DisplayNameFor(model => model.Name)
</th>
<th>
@Html.DisplayNameFor(model => model.Description)
</th>
<th>
@Html.DisplayNameFor(model => model.Price)
</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var item in Model) {
<tr>
<td>
@Html.DisplayFor(modelItem => item.Name)
</td>
<td>
@Html.DisplayFor(modelItem => item.Description)
</td>
<td>
@Html.DisplayFor(modelItem => item.Price)
</td>
<td>
<a asp-action="Edit" asp-route-id="@item.ProductId">Edit</a> |
<a asp-action="Details" asp-route-id="@item.ProductId">Details</a> |
<a asp-action="Delete" asp-route-id="@item.ProductId">Delete</a>
</td>
</tr>
}
</tbody>
</table>


View Edit

@model CleanArch.Application.ViewModels.ProductViewModel

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

<h1>Edit</h1>

<h4>Product</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="ProductId" />
<div class="form-group">
<label asp-for="Name" class="control-label"></label>
<input asp-for="Name" class="form-control" />
<span asp-validation-for="Name" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Description" class="control-label"></label>
<input asp-for="Description" class="form-control" />
<span asp-validation-for="Description" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Price" class="control-label"></label>
<input asp-for="Price" class="form-control" />
<span asp-validation-for="Price" 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");}
}
KERPLUNK 30/08/2022 10:53:38
#500386
A rota do seu edit, não condiz com a rota esperada no método. No seu método de edit é esperado "Id, Name, Description, Price"
KELLY 02/09/2022 16:16:12
#500412
Keplunk, voce diz que na assinatura desse método não está correto?


[HttpPost()]
public IActionResult Edit([Bind("Id, Name, Description, Price")] ProductViewModel productVM)
{
if (ModelState.IsValid)
{
try
{
_productService.Update(productVM);
}
catch (Exception)
{

throw;
}
return RedirectToAction(nameof(Index));
}
return View(productVM);
}
KELLY 02/09/2022 21:09:27
#500413
Kerplunk, alterei o BIND do meu método Edit para ficar semelhante a minha classe de domínio:
[Bind("Id, Name, Description, Price")]

Para
[Bind("ProductId, Name, Description, Price")]

Era só o ProductId, deu certo agora. Só foi falta de atenção minha mesmo.

Obrigada!


Tópico encerrado , respostas não são mais permitidas