2
votes

I use MVC 3, I have a controller with the following code, I cannot get the ViewModel [HttpPost] ActionResult Delete the AdvSlotDeleteViewModel result NULL, I have a similar Action Method for Edit and it is working, Could you help me out on this problem?

// GET: /ManageAdvSlots/Delete/5

    public ActionResult Delete(int id)
    {
        AdvSlot advSlot = advSlotRepository.FindById(id);
        AdvSlotDeleteViewModel deleteViewModel = Mapper.Map<AdvSlot, AdvSlotDeleteViewModel>(advSlot);
        return View(deleteViewModel);
    }

    //
    // POST: /ManageAdvSlots/Delete/5

    [HttpPost]
    public ActionResult Delete(AdvSlotDeleteViewModel deleteViewModel)
    {
        if (ModelState.IsValid)
        {
            AdvSlot advSlot = Mapper.Map<AdvSlotDeleteViewModel, AdvSlot>(deleteViewModel);
            advSlotRepository.Delete(advSlot.AdvSlotId);
            advSlotRepository.Save();
        }
        return RedirectToAction("Index");
    }
}

VIEW

@model MyProject.ViewModels.AdvSlotDeleteViewModel

@{
    ViewBag.Title = "Delete";
}

<h2>Delete</h2>

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

    <div class="display-label">AdvSlotId</div>
    <div class="display-field">
        @Html.DisplayFor(model => model.AdvSlotId)
    </div>

    <div class="display-label">Name</div>
    <div class="display-field">
        @Html.DisplayFor(model => model.Name)
    </div>

    <div class="display-label">Description</div>
    <div class="display-field">
        @Html.DisplayFor(model => model.Description)
    </div>

    <div class="display-label">IsPublished</div>
    <div class="display-field">
        @Html.DisplayFor(model => model.IsPublished)
    </div>

    <div class="display-label">Code</div>
    <div class="display-field">
        @Html.DisplayFor(model => model.Code)
    </div>

    <div class="display-label">Note</div>
    <div class="display-field">
        @Html.DisplayFor(model => model.Note)
    </div>
</fieldset>
@using (Html.BeginForm()) {
    <p>
        <input type="submit" value="Delete" /> |
        @Html.ActionLink("Back to List", "Index")
    </p>
}

VIEW MODEL

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace MyProject.ViewModels
{
    public class AdvSlotDeleteViewModel
    {
        public int AdvSlotId { get; set; }
        public string Name { get; set; }
        public string Description { get; set; }
        public bool IsPublished { get; set; }
        public string Code { get; set; }
        public string Note { get; set; }
    }
}
2
Can you post your Cshtml as well?Gaz Winter
I posted Cshtml and ViewModel I hope can help thanks for your time on this!GibboK

2 Answers

5
votes

You need to put all your form fields inside form block. Otherwise they won't be posted to the server.

Move your <fieldset> inside @using (Html.BeginForm()) { ->> HERE <<- }

PS. For deletes you probably want to post only id, not the whole view model.

1
votes

What people are suggesting is sufficient is to include just the id in a hidden form field:

@using (Html.BeginForm()) {
@Html.HiddenFor(x => x.AdvSlotId)
<p>
    <input type="submit" value="Delete" /> |
    @Html.ActionLink("Back to List", "Index")
</p>
}

You may find that you don't want to check if the model is valid any more. If you have advanced validation on some of the fields, if they're not inside the form they won't be posted back. For instance if "Name" is required, it will fail validation with the above code because only fields inside the form are posted back to the server.