views:

13

answers:

1

I've got a basic ASP.NET MVC 2 application. I've got adding and editing rows working just fine, but deleting won't work. The Delete view gets the correct record on the GET, but when posting back, the parameter that gets passed is empty, as in CategoryID = 0, all empty values. Because of that, no object is found to be deleted from the database and an exception is thrown. How can I get the correct Category to be passed to the HttpPost Delete action?

Here's what I've got in the controller:

public ActionResult Delete(int id)
    {
        return View(_categoryRespository.Get(id));
    }

    [HttpPost]
    public ActionResult Delete(Category categoryToDelete)
    {
        try
        {
            _categoryRespository.Delete(categoryToDelete);
            return RedirectToAction("Index");
        }
        catch
        {
            return View();
        }
    }

This is the Delete view, which as I said correctly displays the data on the GET:

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<MVCApp.Models.Category>" %>

<h2>Delete</h2>

<h3>Are you sure you want to delete this?</h3>
<fieldset>
    <legend>Fields</legend>

    <div class="display-label">CategoryID</div>
    <div class="display-field"><%: Model.CategoryID %></div>

    <div class="display-label">SectionName</div>
    <div class="display-field"><%: Model.SectionName %></div>

    <div class="display-label">CategoryName</div>
    <div class="display-field"><%: Model.CategoryName %></div>

    <div class="display-label">Content</div>
    <div class="display-field"><%: Model.Content %></div>

</fieldset>
<% using (Html.BeginForm()) { %>
    <p>
        <input type="submit" value="Delete" /> |
        <%: Html.ActionLink("Back to List", "Index") %>
    </p>
<% } %>

A: 

Your form is not actually POSTing anything. You can add a hidden input with CategoryID, and then create a static Delete method in your repository that will accept CategoryID as a parameter (or instantiate a category by CategoryID and then call your existing Delete method).

Controller

public ActionResult Delete(int id) 
{ 
    return View(_categoryRespository.Get(id)); 
} 

[HttpPost] 
public ActionResult Delete(int categoryID) 
{ 
    try 
    { 
        _categoryRespository.Delete(categoryID); 
        return RedirectToAction("Index"); 
    } 
    catch 
    { 
        return View(); 
    } 
} 

View

<h2>Delete</h2> 

<h3>Are you sure you want to delete this?</h3> 
<fieldset> 
    <legend>Fields</legend> 

    <div class="display-label">CategoryID</div> 
    <div class="display-field"><%: Model.CategoryID %></div> 

    <div class="display-label">SectionName</div> 
    <div class="display-field"><%: Model.SectionName %></div> 

    <div class="display-label">CategoryName</div> 
    <div class="display-field"><%: Model.CategoryName %></div> 

    <div class="display-label">Content</div> 
    <div class="display-field"><%: Model.Content %></div> 

</fieldset> 
<% using (Html.BeginForm()) { %> 
    <p> 
        <input type="hidden" name="categoryID" value="<%: Model.CategoryID %>" />
        <input type="submit" value="Delete" /> | 
        <%: Html.ActionLink("Back to List", "Index") %> 
    </p> 
<% } %> 
RedFilter
Thanks Red. That solution doesn't work exactly as is, but it got me on the right track. I can't change the HttpPost Delete method to just take an int, because the other Delete method already has that signature. So I changed it to take an int and a string and added hidden fields for categoryID and categoryName. Works like a champ :)
witters
Great, good catch on the duplicate signature, did not notice that.
RedFilter