Kayra
Kayra

Reputation: 165

Adding Delete functionality to my Edit controller in MVC

I'm trying to figure out how to have an edit function and a delete function from the same page in my application. At the moment my controller looks like this:

    [HttpPost]
    public ActionResult Edit(CodeTagViewModel codeTagViewModel, FormCollection collection)
    {
        if (ModelState.IsValid)
        {

            List<Tag> tagsToAdd = new List<Tag>();

            codeTagViewModel.Tags = db.Tags.ToList();
            foreach (Tag tag in codeTagViewModel.Tags)
            {
                if (collection[tag.TagID.ToString()].ToString().Contains("true"))
                {
                    tagsToAdd.Add(tag);
                }
            }

            codeTagViewModel.SelectedTags = tagsToAdd;

            Code code = db.Code.Find(codeTagViewModel.CodeID);
            MapModelToCode(codeTagViewModel, code);

            db.Entry(code).State = EntityState.Modified;
            db.SaveChanges();
            return View(codeTagViewModel);
        }
        return RedirectToAction("Index");
    }

    [HttpPost, ActionName("Delete")]
    public ActionResult Edit(CodeTagViewModel codeTagViewModel, FormCollection collection)
    {
        if (ModelState.IsValid)
        {

            List<Tag> tagsToAdd = new List<Tag>();

            codeTagViewModel.Tags = db.Tags.ToList();
            foreach (Tag tag in codeTagViewModel.Tags)
            {
                if (collection[tag.TagID.ToString()].ToString().Contains("true"))
                {
                    tagsToAdd.Add(tag);
                }
            }

            codeTagViewModel.SelectedTags = tagsToAdd;

            Code code = db.Code.Find(codeTagViewModel.CodeID);
            MapModelToCode(codeTagViewModel, code);

            db.Code.Remove(code);
            db.SaveChanges();
            return View(codeTagViewModel);
        }
        return RedirectToAction("Index");
    }

And I've got the two buttons in my Edit view:

    <p>
        <input type="submit" value="Save" />
    </p>
    <p>
        <input type="submit" value="Delete" />
    </p>

And my view model looks like this:

public class CodeTagViewModel
{
    public List<Tag> Tags { get; set; }
    public List<Tag> SelectedTags { get; set; }        

    public int CodeID { get; set; }
    public string Title { get; set; }
    public string Description { get; set; }
    public DateTime DateAdded { get; set; }
    public DateTime LastUpdated { get; set; }
    public string Project { get; set; }
    public string CMS { get; set; }
    public int DotNetVersion { get; set; }
    public string Dependencies { get; set; }
    public string Author { get; set; }
    public string CodeFile { get; set; }
    public string TFSLocation { get; set; }

}

At the moment the delete button is doing nothing, it's not hitting the code at all.

I'm new to MVC and trying to figure out how it handles all of the background stuff so any help would be greatly appreciated.

EDIT: I've also looked into the routing aspect and put in:

    //
    // POST: /Code/Edit/5

Above the delete function (it's the same as the one for the edit) and still nothing.

Upvotes: 2

Views: 3021

Answers (5)

Mathew Thompson
Mathew Thompson

Reputation: 56429

That's because both the Edit and Delete button both do the same thing, they simply post the form. So they will always post to the same place.

You should change your delete button to be an ActionLink, then change your Delete method to be a HttpGet, pass in the ID of the item you want to delete and then retrieve and delete it.

Like this:

@Html.ActionLink("Delete", "Delete", "Code", new { CodeID = Model.CodeID })

Then in your action method:

[HttpGet]
public ActionResult Delete (int CodeID)
{
   //perform deletion
}

Otherwise, you'd have to use Javascript to automatically change the post URL of the form depending on which button was clicked, which is nasty.

Upvotes: 1

NicoJuicy
NicoJuicy

Reputation: 3528

Problem:

Both buttons submit the parent form, which is probably the same in your solution.

Background Information:

Your HTML Elements are inside a form element, if you submit through a button (doesn't matter which one). The browser will check the url that is given in the forms attribute.

Solution:

Put EDIT in a seperate form - with a reference to the edit url (with the entire model) and then create a seperate form - with a reference to the delete url- with the ModelID and the Delete button. (not with the entire model!)

Change your function of delete, so it only needs the ModelID as a parameter (instead of the whole model).

Off you go :)

Upvotes: 2

Chethan
Chethan

Reputation: 370

You have two Action methods with the same name and parameters. Doesn't it throw a compile error? Also in the view you have two submit buttons. which action is your form pointing to?

Point your form to the ActionMethod "Edit".

Add name attributes to your submit buttons

 <p>
    <input type="submit" value="Save" name ="Edit"/>
</p>
<p>
    <input type="submit" value="Delete" name="Remove"/>
</p>

Then in the controller action method:

 [HttpPost]
public ActionResult Edit(CodeTagViewModel codeTagViewModel, FormCollection collection)
{
    if (ModelState.IsValid)
    {
       if((collection["Edit"]=="Save") && (collection["Remove"] == null)
        {
           // perform edit operation
        }
        else if((collection["Edit"]== null) && (collection["Remove"] == Delete)
        {
           // perform delete operation
        }
    }
}

Upvotes: 0

qujck
qujck

Reputation: 14580

Try using the [HttpDelete] attribute

Upvotes: 0

Moriya
Moriya

Reputation: 7906

Have you trid changing you method name to Delete?

    [HttpPost]
    public ActionResult Delete(CodeTagViewModel codeTagViewModel, FormCollection collection)
    {...

I see no reason for namin the method Edit and setting ActionName to Delete.

Upvotes: 0

Related Questions