Asp.net MVC paraméter valamiért hibás

Asp.net MVC paraméter valamiért hibás
2011-03-23T18:57:13+01:00
2011-03-23T23:11:25+01:00
2022-11-21T06:25:41+01:00
blaces
Sziasztok!

MVC-hez kéne help, néhány dolgot nem értek, hiába olvasom át a Tutorialt a könyvben, meg enged magának úgy tűnik ennyi hibát.

Ezt a hibát miért írja ki?
[The parameters dictionary contains a null entry for parameter 'productId' of non-nullable type 'System.Int32' for method 'System.Web.Mvc.ActionResult Edit(Int32, System.Web.HttpPostedFileBase)' in 'SportsStore.WebUI.Controllers.AdminController'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter.
Parameter name: parameters
/quote]


Idex View - ahol az új termék létrehozását megkezdem
<p><%: Html.ActionLink("Add a new product", "Create") %></p>

Edit View - ahol új termék adatait szerkesztem
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server"> <% if (TempData["message"] != null) { %> <div class="Message"> <%: TempData["message"] %></div> <% } %> <h1>Edit <%: Model.Name %></h1> <% Html.EnableClientValidation(); %> <%using(Html.BeginForm("Edit", "Admin")){ %> <%: Html.EditorForModel( ) %> <input type="submit" value="Save" /> <%: Html.ActionLink("Cancel and return to List","Index") %> <% } %> </asp:Content>

Controllok:
public ActionResult Create() { return View("Edit", new Product()); } [HttpPost] public ActionResult Edit(int productId, HttpPostedFileBase image) { Product product = productId == 0 ? new Product() : productsRepository.Products.First(x => x.ProductID == productId); TryUpdateModel(product); if (ModelState.IsValid) { productsRepository.SaveProduct(product); TempData["message"] = product.Name + " has been saved."; return RedirectToAction("Index"); } else // Validation error, so redisplay same view return View(product); }

Szal nem értem... azt sem igazán értem, hogy miért baj az neki, ha a függvény paraméterében lévő int productId helyett int id van? és akkor a fv-en belül is id-t használok...
Holot a Products osztályban ProductID van, és sehol máshol nem találok productId-t... Miért ahhoz ragaszkodik? A könyv nem írja... frászt kapok tőle, csak a billentyűzet ütögetése nyugtat meg :D

És azt a hibát hogyan tudnám kezelni? Hol? Mert én már nem tudom... Hiába másolgattam a könyv tutoriáljának a forrását, még úgy sem...
Mutasd a teljes hozzászólást!
OK, én írtam rosszat. A kód alapjáraton jó, de én máshogy oldanám meg, valahogy így:

[HttpPost] public ActionResult Edit(Product product, HttpPostedFileBase image) { if (ModelState.IsValid) { if (image != null) { product.ImageMimeType = image.ContentType; product.ImageData = new byte[image.ContentLength]; image.InputStream.Read(product.ImageData, 0, image.ContentLength); } productsRepository.SaveProduct(product); TempData["message"] = product.Name + " has been saved."; return RedirectToAction("Index"); } else // Validation error, so redisplay same view return View(product); }

A jelenlegi megoldással az a gáz, hogy ha pl. Entity Frameworkot használnál, akkor a TryUpdateModelnél az elszállna. Szívtam vele sokat régen, de amúgy is rossz megoldás a prezentációs rétegből platformfüggően frissíteni az adatokat, ez a repository feladata lenne a te kódódban.

A könyv a delete-nél is egy kicsit leegyszerűsít, GET-el nem lenne szabad változtatni (törölni az adatbázisból). Csináld inkább POST-al, a view valami ilyesmi lesz:

<% using(Html.BeginForm("Delete", "Product", FormMethod.Post)){%> <%:Html.HiddenFor(x=>x.ProductID) %> <input type="submit" value="Delete"/> <%} %>

És ez a kód már menni fog a Delete függvényeddel. Adatbázisba meg nem érdemes turkálni, a hiba nem ott lesz.
Mutasd a teljes hozzászólást!

  • Hello,

    egy kicsit meg van kavarva a dolog. Az Edit függvény így kéne, hogy kinézzen:

    [HttpGet] public ActionResult Edit (int productID) { //termék kikeresése az adatbázisól }

    Majd kéne egy POST-ot kezelő függvény, ahol a modelledet felötltöd a képet/írsz az adatbázisba.

    [HttpPost] public ActionResult Edit (Product product, HttpPostedFileBase image) { //képfeltötlés, adatbázis, stb. }

    A kivételt meg azért dobja, mert a productId nem nullable, vagyis valahonnan kell neki egy értéket keríteni, amit nem kap meg. Javaslom a query string használatát (akár ?productID=valami).

    A productId-hez meg azért ragaszkodik, mert emlékeim szerint reflectionnel keresi az azonos nevű értékeket a formban/query stringben, és azokat rendeli össze, tehát az id nem nyerő. De ez nem száz százalék.
    Mutasd a teljes hozzászólást!
  • A könyv tutorial alapján ez az eredeti... ezt követtem, az edit-nél meg igaz, azt benthagytam...

    Illetve, még az a nagy bajom, hogy a delete függvényre is ugyanezt a hibát dobja....

    A tutorial eredeti kódja:
    using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using SportsStore.Domain.Abstract; using SportsStore.Domain.Entities; namespace SportsStore.WebUI.Controllers { [Authorize] public class AdminController : Controller { private IProductsRepository productsRepository; public AdminController(IProductsRepository productsRepository) { this.productsRepository = productsRepository; } public ViewResult Index() { return View(productsRepository.Products.ToList()); } public ViewResult Edit(int productId) { var product = productsRepository.Products.First(x => x.ProductID == productId); return View(product); } [HttpPost] public ActionResult Edit(int productId, HttpPostedFileBase image) { Product product = productId == 0 ? new Product() : productsRepository.Products.First(x => x.ProductID == productId); TryUpdateModel(product); if (ModelState.IsValid) { if (image != null) { product.ImageMimeType = image.ContentType; product.ImageData = new byte[image.ContentLength]; image.InputStream.Read(product.ImageData, 0, image.ContentLength); } productsRepository.SaveProduct(product); TempData["message"] = product.Name + " has been saved."; return RedirectToAction("Index"); } else // Validation error, so redisplay same view return View(product); } public ViewResult Create() { return View("Edit", new Product()); } public RedirectToRouteResult Delete(int productId) { var product = productsRepository.Products.First(x => x.ProductID == productId); productsRepository.DeleteProduct(product); TempData["message"] = product.Name + " was deleted"; return RedirectToAction("Index"); } } }
    Mutasd a teljes hozzászólást!
  • Az az érdekes, hogy ha a könyv tutorialjához csatolom az adatbázisomat, ugyanúgy jelentkezik ez a probléma!

    Lehet az adatbázisban engedélyeznem kéne a null-okat? De az ID-nál furcsa...
    Mutasd a teljes hozzászólást!
  • OK, én írtam rosszat. A kód alapjáraton jó, de én máshogy oldanám meg, valahogy így:

    [HttpPost] public ActionResult Edit(Product product, HttpPostedFileBase image) { if (ModelState.IsValid) { if (image != null) { product.ImageMimeType = image.ContentType; product.ImageData = new byte[image.ContentLength]; image.InputStream.Read(product.ImageData, 0, image.ContentLength); } productsRepository.SaveProduct(product); TempData["message"] = product.Name + " has been saved."; return RedirectToAction("Index"); } else // Validation error, so redisplay same view return View(product); }

    A jelenlegi megoldással az a gáz, hogy ha pl. Entity Frameworkot használnál, akkor a TryUpdateModelnél az elszállna. Szívtam vele sokat régen, de amúgy is rossz megoldás a prezentációs rétegből platformfüggően frissíteni az adatokat, ez a repository feladata lenne a te kódódban.

    A könyv a delete-nél is egy kicsit leegyszerűsít, GET-el nem lenne szabad változtatni (törölni az adatbázisból). Csináld inkább POST-al, a view valami ilyesmi lesz:

    <% using(Html.BeginForm("Delete", "Product", FormMethod.Post)){%> <%:Html.HiddenFor(x=>x.ProductID) %> <input type="submit" value="Delete"/> <%} %>

    És ez a kód már menni fog a Delete függvényeddel. Adatbázisba meg nem érdemes turkálni, a hiba nem ott lesz.
    Mutasd a teljes hozzászólást!
  • köszönöm szépen a választ!
    Mutasd a teljes hozzászólást!
Tetszett amit olvastál? Szeretnél a jövőben is értesülni a hasonló érdekességekről?
abcd