1

I have a form for deleting an object from a table. I would like to put a textfield which would validate the input before pressing the Delete button.

The entity model of the objects looks like this (it has many more attributes, but I just left the important one):

public partial class card
{
    public string reason { get; set; }
}

The controller method of the POST (delete) request looks like this:

// POST: /card/Delete/5

    [HttpPost, ActionName("Delete")]
    [ValidateAntiForgeryToken]
    public ActionResult DeleteConfirmed(int id)
    {
        card temp_card = db.cardss.Find(id);
        temp_card.deleted = true;
        db.SaveChanges();

        if (ModelState.IsValid)
            return RedirectToAction("Index");

        return View(temp_card);
    }

I've read, I have to create another class and use MetaDataAnnotations for this to work, since I'm using entity models. So I wrote this:

[MetadataType(typeof(CardMetaData))]
public partial class card
{
    public string reason { get; set; }
}

public class CardMetaData
{
    [Required(ErrorMessage = "Write a reason for deletion.")]
    public string reason { get; set; }
}

And in my Delete.aspx are the following lines:

 <%= Html.ValidationSummary("Delete was unsuccessful.") %>
 <div class="display-field">
    <%: Html.TextBoxFor(model => model.reason) %>
    <%: Html.ValidationMessageFor(model => model.reason) %>
 </div>

This doesn't display a message if I press the delete button and the textfield is empty. What am I missing?

TheAptKid
  • 1,559
  • 3
  • 25
  • 47
  • I'm not sure you need to add the reason property to the new partial class, just the metadata class - see this example: [http://www.asp.net/mvc/tutorials/older-versions/models-%28data%29/validation-with-the-data-annotation-validators-cs](http://www.asp.net/mvc/tutorials/older-versions/models-%28data%29/validation-with-the-data-annotation-validators-cs) – markpsmith Apr 08 '14 at 09:05
  • The properties in the partial class were generated there. I did not add them. – TheAptKid Apr 08 '14 at 09:12
  • You need to code `if (ModelState.IsValid) return View("ViewThatIsReturning",modelClassName);`. Your DeleteConfirmed method must take your modelClass as a parameter so you can pass it back to the view so the errors will display if `!ModelState.IsValid` – CSharper Apr 08 '14 at 14:52

2 Answers2

1

You'll need a view model with a [Required] attribute for the Reason property

public class DeleteConfirmViewModel
{
    [Required]
    public string Reason { get; set; }
}

Then rework your DeleteConfirmed action. You're current implementation is just not working because you first update the database and then validate if your input model is correct. Next is that you should not redirect in case of a non valid model because you will loose the ModelState containing the error (messages). A correct implementation of DeleteConfirmed will look like this:

[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public ActionResult DeleteConfirmed(int id, DeleteConfirmViewModel viewModel)
{
    if (ModelState.IsValid)
        return View(viewModel);

    card temp_card = db.cardss.Find(id);
    temp_card.deleted = true;
    temp_card.reason = viewModel.Reason;
    db.SaveChanges();

    return View(temp_card);
}

In you're view you will need to show a validation message in case no reason was given

@Html.ValidationMessageFor(m => m.Reason)

So a working input field setup for the reason field in your view could look like this

@Html.LabelFor(m => m.Reason)
@Html.EditorFor(m => m.Reason)
@Html.ValidationMessageFor(m => m.Reason)

Edit

To render the DeleteConfirmed view you'll need to create a view model and pass it to the view

[HttpGet, ActionName("Delete")]
public ActionResult DeleteConfirmed(int id)
{
    return View(new DeleteConfirmViewModel());
}
saintedlama
  • 6,838
  • 1
  • 28
  • 46
  • Tried this, but it didn't work. I think the problem is the "m => m.Reason" is pointing to the partial class model "card" instead of the newly created "DeleteConfirmViewModel". – TheAptKid Apr 08 '14 at 09:16
0
[HttpPost]
public ActionResult ControllerName(ModelClassName viewModel)
{
   if (!ModelState.IsValid)
   return View("ViewName", viewModel);//passes validation errors back to the view

   //do w.e
}
CSharper
  • 5,420
  • 6
  • 28
  • 54