Reputation: 5670
I am trying to delete an entity from Index view page like this
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<button type="submit" value="delete" formaction="/Issue/Delete">Delete</button>
}
on this button click I want my DeleteConfirmed Action inside controller to happen (not go to another delete page).
Inside controller
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public ActionResult DeleteConfirmed(int id)
{
Issue issue = _db.Issues.Find(id);
_db.Issues.Remove(issue);
_db.SaveChanges();
return RedirectToAction("Index");
}
Right now it throws an error
The parameters dictionary contains a null entry for parameter 'id' of non-nullable type 'System.Int32' for method 'System.Web.Mvc.ActionResult DeleteConfirmed(Int32)' in 'DiagnosisApp.Controllers.IssueController'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter.
Parameter name: parameters
Can anyone point out what is the correct approach to achieve this?
Upvotes: 0
Views: 3168
Reputation: 24529
From the Error
The parameters dictionary contains a null entry for parameter 'id'
tells us that you have not actually passed anything to your controller. So, to 'pass' the id value to your controller, you could use an ActionLink
similar to:
@Html.ActionLink("Delete", "Delete", new { id=item.PrimaryKeyValue })
using your model's data within your view.
This 'ActionLink' will link to your CRUD scaffolding (in which I believe you're already using) within your controller;
Something like this:
// GET: message/Delete/5
public ActionResult Delete(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
message message = db.messages.Find(id);
if (message == null)
{
return HttpNotFound();
}
return View(message);
}
which will automatically bring you to a 'delete confirmation page'. However, you might want to alter this into something like:
// POST: message/Delete/5
public ActionResult Delete(int? id)
{
if(id !=null){
message message = db.messages.Find(id);
db.messages.Remove(message);
db.SaveChanges();
return RedirectToAction("Index");
}
else
{
return HttpNotFound();
}
}
This method 'skips' the delete confirmation page, whilst still keeping validation over testing if the id isn't null. However, further validation may be required to test if the id is actually found in the db.
Which first tests if you have sent in a id value, and if so, completed the 'delete' action within your database.
Note
These Actions are freely available when using MVC's scaffolding
Upvotes: 1
Reputation: 151578
You're not providing the ID in your POST nor your URL.
Either POST to the URL containing the ID:
@using (Html.BeginForm("Delete", "Controller", new { id = Model.ID }, FormMethod.Post))
{
// ...
}
Or POST the ID as a hidden form value:
@using (Html.BeginForm("Delete", "Controller", FormMethod.Post))
{
@Html.HiddenFor(m => m.ID)
// ...
}
Upvotes: 2
Reputation: 1694
Try the following code. It will not redirect you to delete page until you confirm it.
@Html.ActionLink("About", "delete", "Issue", new { id = "yourId" }, new { onclick = "return confirm('Are you sure you wish to delete this article?');" })
Upvotes: 0
Reputation: 18569
Your action state that the delete need an ID, but you didn't pass it from your view when you submit the form.
Try change your code like this. Don't forget to change the hidden value with the ID.
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<input type="hidden" name="id" id="id" value="<THE VALUE>"/>
<button type="submit" value="delete" formaction="/Issue /Delete">Delete</button>
}
Upvotes: -1