Добавление проверки с помощью DataAnnotations

У меня есть форма для удаления объекта из таблицы. Я хотел бы поместить текстовое поле, которое будет проверять ввод, прежде чем нажимать кнопку "Удалить".

Сущность модели объектов выглядит так (она имеет гораздо больше атрибутов, но я просто оставил важный):

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

Метод контроллера запроса POST (delete) выглядит следующим образом:

// 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);
    }

Я прочитал, мне нужно создать другой класс и использовать MetaDataAnnotations для этого, потому что я использую модели сущностей. Поэтому я написал следующее:

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

И в моем Delete.aspx есть следующие строки:

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

Это не отображает сообщение, если я нажимаю кнопку удаления, и текстовое поле пуст. Что мне не хватает?

Ответ 1

Вам понадобится модель представления с атрибутом [Required] для свойства Reason

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

Затем переработайте свое действие DeleteConfirmed. Текущая реализация просто не работает, потому что вы сначала обновляете базу данных, а затем проверяете правильность вашей модели ввода. Далее вы не должны перенаправлять в случае недействительной модели, потому что вы потеряете ModelState, содержащую ошибку (сообщения). Правильная реализация DeleteConfirmed будет выглядеть так:

[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);
}

В вашем представлении вам нужно будет показать сообщение о проверке в случае, если не была дана причина

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

Таким образом, рабочая настройка поля ввода для поля причины в вашем представлении может выглядеть так:

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

Edit

Чтобы отобразить представление DeleteConfirmed, вам необходимо создать модель представления и передать ее в представление

[HttpGet, ActionName("Delete")]
public ActionResult DeleteConfirmed(int id)
{
    return View(new DeleteConfirmViewModel());
}

Ответ 2

[HttpPost]
public ActionResult ControllerName(ModelClassName viewModel)
{
   if (!ModelState.IsValid)
   return View("ViewName", viewModel);//passes validation errors back to the view

   //do w.e
}