When in view mode, I try to fill in and get the date, it always turns out to be empty, but for example, the string field is filled in. And if I don't use the ViewModel, but only the Booking model, the date is filled in. I would like the date to be filled in with the viewmodel as well...
Controller:
public async Task<IActionResult> CheckOut3(CheckoutModel broom)
{
if (ModelState.IsValid)
{
_context.Add(broom);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
return View(broom);
}
Model:
public class Booking
{
public int Id { get; set; }
public Room Room { get; set; }
public string LastName { get; set; }
public string FirstName { get; set; }
[DisplayFormat(ApplyFormatInEditMode =true, DataFormatString = "{0:yyyy-MM-dd}")]
public DateTime? CheckInDate{ get; set; }
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:yyyy-MM-dd}")]
public DateTime? CheckOutDate { get; set; }
}
ViewModel:
public class CheckoutModel
{
public Booking booking {get; set;}
public Room room { get; set; }
}
View:
<form asp-action="Checkout3">
<div class="row">
<!--Grid column-->
<div class="col-lg-6 col-md-12 mb-4">
<label asp-for="booking.CheckInDate">CheckIn</label>
<input asp-for="booking.CheckInDate" class="form-control" type="datetime-local" name="CheckInDate" />
<span asp-validation-for="booking.CheckInDate" class="text-danger"></span>
</div>
<!--Grid column-->
<div class="col-lg-6 col-md-6 mb-4">
<label asp-for="booking.CheckOutDate">CheckOut</label>
<input asp-for="booking.CheckOutDate" class="form-control" type="date" name="CheckOutDate" />
<span asp-validation-for="booking.CheckOutDate" class="text-danger"></span>
</div>
</div>
<div class="form-group">
<input type="submit" value="Checkout" class="btn btn-primary" />
</div>
</form>
The problem is, you're posting CheckInDate and CheckOutDate in the html form, while it should be booking.CheckInDate and booking.CheckOutDate. Remove the name in your view, so name will be set with the value provided in asp-for.
<!--Grid column-->
<div class="col-lg-6 col-md-12 mb-4">
<label asp-for="booking.CheckInDate">CheckIn</label>
<input asp-for="booking.CheckInDate" class="form-control" type="datetime-local" />
<span asp-validation-for="booking.CheckInDate" class="text-danger"></span>
</div>
<!--Grid column-->
<div class="col-lg-6 col-md-6 mb-4">
<label asp-for="booking.CheckOutDate">CheckOut</label>
<input asp-for="booking.CheckOutDate" class="form-control" type="date" />
<span asp-validation-for="booking.CheckOutDate" class="text-danger"></span>
</div>
Related
I am building a to-do-list project as a practice. It has one relationship to the Member model and the Member model has many relationships to 'to-do-list'
Member controller create method works without any issue but the to-do-list controller throws model state is invalid on Member object property of to-do-list
ToDoList
using System.ComponentModel.DataAnnotations;
namespace To_Do_List.Models
{
public class ToDoList
{
[Key]
public int Id { get; set; }
[Required]
[StringLength(200, MinimumLength = 1, ErrorMessage = "To Do List Item cannot be longer than 200 characters.")]
public string Title { get; set; }
public string Description { get; set; }
[DataType(DataType.Date)]
public DateTime DueDate { get; set; }
public string Priority { get; set; }
public int AssignToId { get; set; }
public Member AssignTo { get; set; }
[Required]
[StringLength(15, ErrorMessage = "The {0} must be at least {2} and at max {1} characters long.")]
[RegularExpression("^(Completed|Not Completed)$", ErrorMessage = "The status must be Completed or Not Completed")]
public string Status { get; set; }
}
}
Member
using Microsoft.Build.Framework;
namespace To_Do_List.Models
{
public class Member
{
public int Id { get; set; }
public string Name { get; set; }
public string Email { get; set; }
[Required]
public ICollection<ToDoList> ToDoLists { get; set; }
}
}
create method of to do list controller
public async Task<IActionResult> Create([Bind("Id,Title,Description,DueDate,Priority,AssignToId,AssignTo, Status")] ToDoList toDoList)
{
if (ModelState.IsValid)
{
_context.Add(toDoList);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
ViewData["AssignToId"] = new SelectList(_context.Members, "Id", "Id", toDoList.AssignToId);
return View(toDoList);
}
View method of to do list
public IActionResult Create()
{
return View();
}
Create.cshtml
#model To_Do_List.Models.ToDoList
#{
ViewData["Title"] = "Create";
}
<h1>Create</h1>
<h4>ToDoList</h4>
<hr />
<div class="row">
<div class="col-md-4">
<form asp-action="Create">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="Title" class="control-label"></label>
<input asp-for="Title" class="form-control" />
<span asp-validation-for="Title" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Description" class="control-label"></label>
<input asp-for="Description" class="form-control" />
<span asp-validation-for="Description" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="DueDate" class="control-label"></label>
<input asp-for="DueDate" class="form-control" />
<span asp-validation-for="DueDate" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Priority" class="control-label"></label>
<input asp-for="Priority" class="form-control" />
<span asp-validation-for="Priority" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Status" class="control-label"></label>
<input asp-for="Status" class="form-control" />
<span asp-validation-for="Status" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-primary" />
</div>
</form>
</div>
</div>
<div>
<a asp-action="Index">Back to List</a>
</div>
#section Scripts {
#{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}
Member controller create method works without any issue but the
to-do-list controller throws model state is invalid on Member object
property of to-do-list
Well, I have succssfully reproducced your issue and your ModelState.IsValid false is logical. Because, when you leave public Member AssignTo { get; set; } with default annotation it means required. whilist, you haven't pass any property from your view consequently, your bindings always be false as you have defined it into the [Bind] property that is AssignTo However, value has not been pass to it.
How to resolve:
In this scenario, you either has to pass AssignTo to your create action or make it nullable using ? annotation as following:
public Member? AssignTo { get; set; }
Note: If you don't want to set AssignTo as nullable then you have to pass all property value from your view as following:
<div class="form-group">
<label asp-for="AssignTo.Name" class="control-label"></label>
<input asp-for="AssignTo.Name" class="form-control" />
<span asp-validation-for="AssignTo.Name" class="text-danger"></span>
</div>
Here, I am passing only AssignTo.Name you have to pass rest of the values.
Output:
Note: If you would like to know more details on it you could check our official document here.
I have two models, User and Employee. I have to make a registration form, where I'll be taking inputs for both these models. I know how to do this with a single model but I cannot figure out how to do it for multiple models. I have read some suggestions here where they've suggested using a ViewModel but I cannot configure it properly.
User:
public class UserModel
{
public int Id { get; set; }
public string UserName { get; set; }
public string Email { get; set; }
public string Password { get; set; }
}
Employee:
public class EmployeeModel
{
public int Id { get; set; }
public string Name { get; set; }
public int Phone { get; set; }
public int UserId { get; set; }
public int LocationId { get; set; }
}
ViewModel:
public class UserEmployee
{
public UserModel user { get; set; }
public EmployeeModel emp { get; set; }
}
My controllers:
[HttpGet]
public ActionResult RegisterEmployee()
{
var model = new UserEmployee();
model.user = new UserModel();
model.emp = new EmployeeModel();
return View(model);
}
[HttpPost]
public ActionResult RegisterEmployee(UserEmployee useremp)
{
return View();
}
Form:
#model ZeroHungerProject.Models.UserEmployee
///////
<form action="" method="post">
<div class="form-group">
<label>User Name</label>
<input type="text" name="#Model.user.UserName" class="form-control" placeholder="User Name">
</div>
<div class="form-group">
<label>Email address</label>
<input type="email" name="#Model.user.Email" class="form-control" placeholder="Email">
</div>
<div class="form-group">
<label>Phone</label>
<input type="number" name="#Model.emp.Phone" class="form-control" placeholder="Phone">
</div>
<div class="form-group">
<label>Password</label>
<input type="password" name="#Model.user.Password" class="form-control" placeholder="Password">
</div>
<div class="form-group">
<label>Confirm Password</label>
<input type="password" class="form-control" placeholder="Confirm Password">
</div>
<button type="submit" class="btn btn-primary btn-flat m-b-30 m-t-30">Register</button>
I tried using the viewmodel to post the inputs. But no data is passing from the form.
Remove the prefix "#Model." from the name attribute.
<form action="" method="post">
<div class="form-group">
<label>User Name</label>
<input type="text" name="user.UserName" class="form-control" placeholder="User Name">
</div>
<div class="form-group">
<label>Email address</label>
<input type="email" name="user.Email" class="form-control" placeholder="Email">
</div>
<div class="form-group">
<label>Phone</label>
<input type="number" name="emp.Phone" class="form-control" placeholder="Phone">
</div>
<div class="form-group">
<label>Password</label>
<input type="password" name="user.Password" class="form-control" placeholder="Password">
</div>
<div class="form-group">
<label>Confirm Password</label>
<input type="password" class="form-control" placeholder="Confirm Password">
</div>
<button type="submit" class="btn btn-primary btn-flat m-b-30 m-t-30">Register</button>
</form>
And to pass ConfirmPassword, you need to provide the name attribute to the <input> element for ConfirmPassword and add the ConfirmPassword property in the UserModel class.
<input type="password" name="user.ConfirmPassword" class="form-control" placeholder="Confirm Password">
public class UserModel
{
...
public string ConfirmPassword { get; set; }
}
Controller
public async Task<IActionResult> Create(IFormFile? StaffPhoto, CollectionViewModel collectionModel)
{
if (StaffPhoto != null){...} // issue is StaffPhoto value is null
}
View Model
namespace Website.Models
{
public class CollectionViewModel
{
public Staff staff { get; set; }
public Contact contact { get; set; }
}
}
Entity Model
public class Staff
{
public int StaffId { get; set; }
[DisplayName("First Name")]
[Required]
public string StaffFirstName { get; set; }
[DisplayName("Last Name")]
[Required]
public string StaffLastName { get; set; }
[DisplayName("Photo")]
public string? StaffPhoto { get; set; }
}
View
#model CollectionViewModel
<form asp-action="Create" enctype="multipart/form-data" method="post" class="row g-3 mt-0">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="col">
<label asp-for="staff.StaffFirstName" class="form-label"></label>
<input asp-for="staff.StaffFirstName" class="form-control" />
<span asp-validation-for="staff.StaffFirstName" class="text-danger"></span>
</div>
<div class="col">
<label asp-for="staff.StaffLastName" class="form-label"></label>
<input asp-for="staff.StaffLastName" class="form-control" />
<span asp-validation-for="staff.StaffLastName" class="text-danger"></span>
</div>
<div class="col-md-3">
<label asp-for="staff.StaffPhoto" class="form-label"></label>
<input asp-for="staff.StaffPhoto" type="file" accept="image/*" class="form-control" />
<span asp-validation-for="staff.StaffPhoto" class="text-danger"></span>
#{if (ViewBag.fileUploadErrorMessage != null)
{
<span class="text-danger">#ViewBag.fileUploadErrorMessage</span>
}
}
</div>
<div class="col">
<input type="submit" value="Create" class="btn btn-primary" />
<a asp-action="Create" class="btn btn-secondary">Reset All</a>
</div>
</form>
You should add IFormFile in model.
public class CollectionViewModel
{
public Staff staff { get; set; }
public IFormFile StaffPhoto { get; set; }
public Contact contact { get; set; }
}
set StaffPhoto to asp-for in view.
<input asp-for="StaffPhoto" type="file" accept="image/*" class="form-control" />
In this method, I want to check that the var Total don't exceed the TotalMonths variable.
The problem is, that the var Total is always received with a value of zero, and I don't understad why. Here the method:
/********EDIT MONTH DETAILS POST*********/
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult EditMonthDetail(BudgetViewModel budget)
{
//var Total = budget.FBudget.UnitPrice * budget.FBudget.Quantity;
//budget.FBudget.TotalAmount = budget.FBudget.UnitPrice * budget.FBudget.Quantity;
//var Total = _unitOfWork.Budget.Get(budget.FBudget.TotalAmount);
var Total = BudgetVM.FBudget.TotalAmount;
/*Always retrieved with 0*/
if (Total >= budget.FBudget.TotalMonths)
{
_unitOfWork.Budget.EditMonthDetails(BudgetVM.FBudget);
_unitOfWork.Save();
return RedirectToAction("Success");
}
return RedirectToAction("FailedTotal");
}
Here is how the TotalAmount is implemented in the model:
public float TotalAmount
{
get
{
return UnitPrice * Quantity;
}
}
Here is the View with a form of type Post:
#{
Layout = "~/Views/Shared/_Layout.cshtml";
var title = "title";
}
<form method="post" asp-action="EditMonthDetail">
<div class="row px-2 mx-2">
<div class="col-12">
#if (Model.FBudget.BudgetId != 0)
{
<input type="hidden" asp-for="FBudget.BudgetId" />
title = "Edit Month details";
}
<br />
<h2 class="text-primary">#title</h2>
</div>
<br />
<div class="col-8">
<div class="form-group row">
<div class="col-4">
<label asp-for="FBudget.Jan"></label>
</div>
<div class="col-8">
<input asp-for="FBudget.Jan" class="form-control" />
<span asp-validation-for="FBudget.Jan" class="text-danger"></span>
</div>
</div>
</div>
<br />
<br />
<div class="col-8">
<div class="form-group row">
<div class="col-4">
<label asp-for="FBudget.Feb"></label>
</div>
<div class="col-8">
<input asp-for="FBudget.Feb" class="form-control" />
<span asp-validation-for="FBudget.Feb" class="text-danger"></span>
</div>
</div>
</div>
<br />
<br />
<div class="col-8">
<div class="form-group row">
<div class="col-4">
<label asp-for="FBudget.Mar"></label>
</div>
<div class="col-8">
<input asp-for="FBudget.Mar" class="form-control" />
<span asp-validation-for="FBudget.Mar" class="text-danger"></span>
</div>
</div>
</div>
<br />
<br />
<div class="col-8">
<div class="form-group row">
<div class="col-4">
<label asp-for="FBudget.Apr"></label>
</div>
<div class="col-8">
<input asp-for="FBudget.Apr" class="form-control" />
<span asp-validation-for="FBudget.Apr" class="text-danger"></span>
</div>
</div>
</div>
<br />
<br />
<div class="col-8">
<div class="form-group row">
<div class="col-4">
<label asp-for="FBudget.May"></label>
</div>
<div class="col-8">
<input asp-for="FBudget.May" class="form-control" />
<span asp-validation-for="FBudget.May" class="text-danger"></span>
</div>
</div>
</div>
<br />
<br />
<div class="col-8">
<div class="form-group row">
<div class="col-4">
<label asp-for="FBudget.Jun"></label>
</div>
<div class="col-8">
<input asp-for="FBudget.Jun" class="form-control" />
<span asp-validation-for="FBudget.Jun" class="text-danger"></span>
</div>
</div>
</div>
<br />
<br />
<div class="col-8">
<div class="form-group row">
<div class="col-4">
<label asp-for="FBudget.Jul"></label>
</div>
<div class="col-8">
<input asp-for="FBudget.Jul" class="form-control" />
<span asp-validation-for="FBudget.Jul" class="text-danger"></span>
</div>
</div>
</div>
<br />
<br />
<div class="col-8">
<div class="form-group row">
<div class="col-4">
<label asp-for="FBudget.Ago"></label>
</div>
<div class="col-8">
<input asp-for="FBudget.Ago" class="form-control" />
<span asp-validation-for="FBudget.Ago" class="text-danger"></span>
</div>
</div>
</div>
<br />
<br />
<div class="col-8">
<div class="form-group row">
<div class="col-4">
<label asp-for="FBudget.Sept"></label>
</div>
<div class="col-8">
<input asp-for="FBudget.Sept" class="form-control" />
<span asp-validation-for="FBudget.Sept" class="text-danger"></span>
</div>
</div>
</div>
<br />
<br />
<div class="col-8">
<div class="form-group row">
<div class="col-4">
<label asp-for="FBudget.Oct"></label>
</div>
<div class="col-8">
<input asp-for="FBudget.Oct"class="form-control" />
<span asp-validation-for="FBudget.Oct" class="text-danger"></span>
</div>
</div>
</div>
<br />
<br />
<div class="col-8">
<div class="form-group row">
<div class="col-4">
<label asp-for="FBudget.Nov"></label>
</div>
<div class="col-8">
<input asp-for="FBudget.Nov"class="form-control" />
<span asp-validation-for="FBudget.Nov" class="text-danger"></span>
</div>
</div>
</div>
<br />
<br />
<div class="col-8">
<div class="form-group row">
<div class="col-4">
<label asp-for="FBudget.Dec"></label>
</div>
<div class="col-8">
<input asp-for="FBudget.Dec"class="form-control" />
<span asp-validation-for="FBudget.Dec" class="text-danger"></span>
</div>
</div>
</div>
<br />
<br />
<div class="col-8">
<div class="form-group row">
<div class="col-8 offset-4">
<button type="submit" class="btn btn-primary form-control">Update</button>
</div>
</div>
</div>
</div>
</form>
I also tried to create a GetTotalAmount() method in the repository but it doesn't seems to work.
What am I doing wrong here?
EDIT
Here is the model:
namespace SalesBudget.Models
{
public class FBudget
{
[Key]
public int BudgetId { get; set; }
[Required(ErrorMessage = "Year is required.")]
public int Year { get; set; }
[Required(ErrorMessage = "FoC is required.")]
public string FreeOfCharge { get; set; }
[Required(ErrorMessage = "Currency is required.")]
public string Currency { get; set; }
[Required(ErrorMessage = "Unit price is required.")]
[Display(Name = "Unit Price")]
public float UnitPrice { get; set; }
public int Jan { get; set; }
public int Feb { get; set; }
public int Mar { get; set; }
public int Apr { get; set; }
public int May { get; set; }
public int Jun { get; set; }
public int Jul { get; set; }
public int Ago { get; set; }
public int Sept { get; set;}
public int Oct { get; set; }
public int Nov { get; set; }
public int Dec { get; set; }
public int TotalMonths
{
get
{
return Jan + Feb + Mar + Apr + May
+ Jun + Jul + Ago + Sept + Oct + Nov + Dec;
}
}
[Display(Name = "Month Nr")]
[Required(ErrorMessage = "Month Nr is required.")]
[Range(1, 12, ErrorMessage = "The value must be between 1 and 12!")]
public string MonthNr { get; set; }
[Display(Name = "Unit of Measure")]
[Required(ErrorMessage = "Unit of Measure is required.")]
public string UnitOfMeasure { get; set; }
[Display(Name = "Quantity")]
[Required(ErrorMessage = "Quantity in untis is required.")]
public int Quantity { get; set; }
public float TotalAmount
{
get
{
return UnitPrice * Quantity;
}
}
public string LastUser
{
//automatically set the last user that used the app
get; set;
}
public int ProgramId
{
//automatically set the last sw that used the app
get; set;
}
public DateTime LastUpdate { get; set; } = DateTime.Now;
//FKs
//Access to ItemMaster
[Display(Name = "Item")]
public int ItemMasterId { get; set; }
public ItemMaster ItemMaster { get; set; }
//Access to Company
[Display(Name = "Company")]
public int CompanyId { get; set; }
public Company Company { get; set; }
//Access to LedgerType
[Display(Name = "Scenario")]
public int LedgerTypeId { get; set; }
public LedgerType LedgerType { get; set; }
//Access to Customer
[Display(Name = "Customer")]
public int CustomerId { get; set; }
public Customer Customer { get; set; }
}
}
And here is the ViewModel:
namespace SalesBudget.Models.ViewModels
{
public class BudgetViewModel
{
public FBudget FBudget { get; set; }
public IEnumerable<FBudget> RecordsList { get; set; }
public IEnumerable<SelectListItem> ItemNumberList { get; set; }
public IEnumerable<SelectListItem> ItemDescriptionList { get; set; }
public IEnumerable<SelectListItem> PharmaFormList { get; set; }
public IEnumerable<SelectListItem> ProductGroupList { get; set; }
public IEnumerable<SelectListItem> CompanyList { get; set; }
public IEnumerable<SelectListItem> LedgerTypeList { get; set; }
public IEnumerable<SelectListItem> LedgerScenarioList { get; set; }
public IEnumerable<SelectListItem> CustomerList { get; set; }
public IEnumerable<SelectListItem> LicensingAreaList { get; set; }
public IEnumerable<SelectListItem> YearsList { get; set; }
public IEnumerable<SelectListItem> CurrencyList { get; set; }
}
}
RESOLVED
I forgot to add hidden input fields in the view in order to retrieve the values that I needed:
<div class="col-12">
#if (Model.FBudget.BudgetId != 0)
{
<input type="hidden" asp-for="FBudget.BudgetId" />
<input type="hidden" asp-for="FBudget.Quantity" />
<input type="hidden" asp-for="FBudget.UnitPrice" />
<input type="hidden" asp-for="FBudget.TotalAmount" />
title = "Edit Month details";
}
<br />
</div>
So now when the form is submitted so are the values captured with hidden fields.
I am trying to validate specific fields from my model before the form is submitted. It works but message doesn't show, this is because name attributes doesn't match.
This is my model:
public class TaskList
{
[Key]
public int Id { get; set; }
[MaxLength(200, ErrorMessage = "Subject field can't have more than 250 characters.")]
[Required(ErrorMessage = "Subject field cannot be empty.")]
[Column(TypeName = "nvarchar")]
public string Subject { get; set; }
[MaxLength(1000, ErrorMessage = "Details field can't have more than 1000 characters.")]
[Column(TypeName = "nvarchar")]
public string Details { get; set; }
[Required(ErrorMessage = "Please select a module.")]
public TaskLabels Label { get; set; }
[Required]
[Column(TypeName = "date")]
public DateTime Created { get; set; }
[Column(TypeName = "date")]
public DateTime? DueDate { get; set; }
[Column(TypeName = "date")]
public DateTime? Completed { get; set; }
}
This is controller action:
[HttpPost]
public IActionResult TaskList(TaskList newTask)
{
_ticketRepo.AddTask(newTask);
return RedirectToAction("TaskList");
}
This is my viewmodel:
public class TaskListViewModel
{
public TaskList ToDo { get; set; }
public IEnumerable<TaskList> TasksList { get; set; }
}
And this is my form:
<div class="modal fade" id="modal-add">
<div class="modal-dialog modal-lg">
<form class="form-horizontal" asp-controller="home" asp-action="TaskList" method="post">
<div class="modal-content">
<div class="modal-header bg-success">
<h4 class="modal-title">Add New To Do Item</h4>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<div class="card-body">
<div class="form-group row">
<label asp-for="ToDo.Subject" class="col-sm-2 col-form-label">Subject</label>
<div class="col-sm-10">
<input type="text" asp-for="ToDo.Subject" name="Subject" class="form-control" placeholder="Subject">
<span asp-validation-for="#Model.ToDo.Subject" class="text-danger"></span>
</div>
</div>
<div class="form-group row">
<label asp-for="ToDo.Details" class="col-sm-2 col-form-label">Details</label>
<div class="col-sm-10">
<textarea asp-for="ToDo.Details" name="Details" class="form-control" placeholder="Provide some details about the task."></textarea>
<span asp-validation-for="ToDo.Details" class="text-danger"></span>
</div>
</div>
<div class="form-group row">
<label asp-for="ToDo.Label" class="col-sm-2 col-form-label">Module</label>
<div class="col-sm-10">
<select name="ToDo.Label" asp-for="Label" asp-items="Html.GetEnumSelectList<TaskLabels>()" class="form-control select2 select2-danger" data-dropdown-css-class="select2-danger" style="width: 100%;">
<option value="" selected="selected">Please select one</option>
</select>
<span asp-validation-for="ToDo.Label" class="text-danger"></span>
</div>
</div>
<div class="form-group row">
<label asp-for="ToDo.DueDate" class="col-sm-2 col-form-label">Date:</label>
<div class="col-sm-10 input-group date" id="duedate" data-target-input="nearest">
<input type="text" name="DueDate" asp-for="ToDo.DueDate" class="form-control datetimepicker-input" data-target="#duedate" />
<div class="input-group-append" data-target="#duedate" data-toggle="datetimepicker">
<div class="input-group-text"><i class="fa fa-calendar"></i></div>
</div>
</div>
</div>
<div asp-validation-summary="All" class="text-danger"></div>
</div>
<!-- /.card-body -->
</div>
<div class="modal-footer justify-content-between">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button type="submit" class="btn btn-primary">Save changes</button>
</div>
</div>
<!-- /.modal-content -->
</form>
</div>
<!-- /.modal-dialog -->
<script src="~/lib/jquery-validation/dist/jquery.validate.min.js"></script><script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"></script>
In my form, if I remove name attribute from input fields, validation works, validation messages are shown but model binding doesn't work and I get null exception error for my properties. What am I doing wrong?
Of course I had to instantiate viewmodel in my controller action! When I did that and removed all name attributes from input fields in my view, everything worked just fine!
[HttpPost]
public IActionResult TaskList(TaskListViewModel model)
{
if (ModelState.IsValid)
{
TaskList taskList = new TaskList
{
Created = DateTime.Now.Date,
Subject = model.ToDo.Subject,
Details = model.ToDo.Details,
DueDate = model.ToDo.DueDate,
Label = model.ToDo.Label
};
_ticketRepo.AddTask(taskList);
return RedirectToAction("TaskList");
}
else
{
return View();
}
}