0
votes

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?

4
post your delete action code also. - Kartikeya Khosla
Not related to the question but as good practice don't use hard coded urls instead make a use of @Url helpers. - Jenish Rabadiya
You need to pass Id to your action method. - Jenish Rabadiya
@JenishRabadiya How? Can you add a code sample? - None
Where does the id come from? a grid? a user input? the viewmodel? show some code plz. - Paul Zahra

4 Answers

2
votes

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)
    // ...
}
1
votes

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

0
votes

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?');" })
-1
votes

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>
}