UPDATE INSERINDO NOVO ITEM EM VEZ DE ATUALIZAR
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");
}
}
}
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");
}
}
}
Mostra o código do form
Oi Kerplunk!
Segue o código da View Index que chama a View Edit e também a ViewEdit completa.
View Index
View Edit
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");}
}
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"
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);
}
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!
[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