Reputation: 397
I'm trying to make a simple form that takes in two required inputs and one optional input (also has one property that is 'hidden' - TaskId
- and set upon loading, and is not changed after being set).
The problem occurs when submitting. The validation is completely skipped, doesn't matter what I put in the box it always goes straight to the method and doesn't display any validation text to the user. Additionally, the ModelState is always valid regardless.
Posting text instead of pictures. Sorry about that guys.
View
@model ScrumBoard.Models.ViewModels.UpdateTaskViewModel
@{
HtmlHelper.ClientValidationEnabled = true;
}
@using (Html.BeginForm("EditTask", "Dashboard", FormMethod.Post, new { @class = "px-4 py-3" }))
{
@Html.AntiForgeryToken()
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
@Html.HiddenFor(o => o.TaskId)
<div class="form-group">
@Html.LabelFor(o => o.Title)
@Html.TextBoxFor(o => o.Title, new { @class = "form-control" })
@Html.ValidationMessageFor(o => o.Title)
</div>
<div class="form-group">
@Html.LabelFor(o => o.Description)
@Html.TextAreaFor(o => o.Description, new { @class = "form-control", rows = 3 })
@Html.ValidationMessageFor(o => o.Description)
</div>
<div class="form-group">
@Html.LabelFor(o => o.Comment)
@Html.TextAreaFor(o => o.Comment, new { @class = "form-control", rows = 2, maxlength = 100 })
@Html.ValidationMessageFor(o => o.Description)
</div>
<button type="submit" class="btn btn-primary">Update</button>
}
ViewModel
public class UpdateTaskViewModel
{
public UpdateTaskViewModel(int taskId)
{
TaskId = taskId;
}
public int TaskId { get; set; }
[Required(ErrorMessage = "Title is required", AllowEmptyStrings = false)]
[AllowHtml]
public string Title { get; set; }
[Required(ErrorMessage = "Description is required", AllowEmptyStrings = false)]
[AllowHtml]
[DataType(DataType.MultilineText)]
public string Description { get; set; }
[AllowHtml]
[DataType(DataType.MultilineText)]
public string Comment { get; set; }
}
Controller
[HttpPost]
public ActionResult EditTask(int taskId, string title, string description, string comment = "")
{
Alert alert;
if (ModelState.IsValid)
{
try
{
DatabaseOperations.UpdateTask(
taskId,
title,
description,
EacId,
comment);
alert = new Alert("Success!", "Updated task.", "alert-success");
}
catch (Exception e)
{
alert = new Alert("Error!", "Failed to update task.", "alert-danger", e);
}
}
else
{
alert = new Alert("Warning!", "ModelState is invalid.", "alert-warning");
}
TempData["Alert"] = alert;
return RedirectToAction("Index");
}
Upvotes: 0
Views: 421
Reputation: 397
Such a simple answer... All that needed to be done was instead of passing each parameter individually to the controller method, just pass the ViewModel and everything works as it should:
[HttpPost]
public ActionResult EditTask(UpdateTaskViewModel model)
{
Alert alert;
if (ModelState.IsValid)
{
try
{
DatabaseOperations.UpdateTask(
model.TaskId,
model.Title,
model.Description,
EacId,
model.Comment);
alert = new Alert("Success!", "Updated task.", "alert-success");
}
catch (Exception e)
{
alert = new Alert("Error!", "Failed to update task.", "alert-danger", e);
}
}
else
{
return PartialView("_UpdateTask")
}
TempData["Alert"] = alert;
return RedirectToAction("Index");
}
PS. Because this is a partial view that I'm using to generate the form, I needed to send back the partial view with the error-ed model back to the main view which I just set in the @using(Html.BeginForm(...))
to replace the html with the partial view.
Upvotes: 1