Data is not binding in ViewModel Nested Class for POST method - c#

When saving the details from the view, the details is not binding into the nested class (BOUser) in ViewModel.The nested class data is showing null(Refer the debug result image). I am using .net core 6 in Mac for the development. Please help me out what I am missed in this coding.
Controller Class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using NearMeBuy.Models.Masters.ViewModels;
namespace NearMeBuyWebApp.Areas.Admin.Controllers
{
[Area("Admin")]
public class TestOPSController : Controller
{
public IActionResult Index()
{
RegisterVM registerVM = new RegisterVM()
{
ApplicationRoles = null,
BOUser = new(),
DepartmentMaster = null,
Mode = 1
};
return View(registerVM);
}
[HttpPost]
public IActionResult Index(RegisterVM vM )
{
if (ModelState.IsValid)
{
return View("Hi");
}
return View();
}
}
}
View Model Class
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
using Microsoft.AspNetCore.Mvc.Rendering;
using NearMeBuy.Models.Tokens.User;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace NearMeBuy.Models.Masters.ViewModels
{
public class RegisterVM
{
public int Mode { get; set; }
//public RegisterModel RegisterModel { get; set; }
public BOUser BOUser { get; set; }
[ValidateNever]
public IEnumerable<SelectListItem> ApplicationRoles { get; set; }
[ValidateNever]
public IEnumerable<SelectListItem> DepartmentMaster { get; set; }
}
}
BOUser Class
using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
using Microsoft.EntityFrameworkCore;
namespace NearMeBuy.Models.Masters
{
public class BOUser
{
public string UserId { get; set; }
[Required(ErrorMessage = "First Name can't be empty")]
public string FirstName { get; set; }
[Required(ErrorMessage = "Last Name can't be empty")]
public string LastName { get; set; }
[Required(ErrorMessage = "Email can't be empty")]
public string Email { get; set; }
[Required(ErrorMessage = "Phone can't be empty")]
public string PhoneNo { get; set; }
[Required(ErrorMessage = "Username can't be empty")]
public string UserName { get; set; }
[Required(ErrorMessage = "Account Confirmation can't be empty")]
public bool AccountConfirmed { get; set; } = false;
/// <summary>
/// The user type field to store the type of user 1: for BackOffice User , 2: for Supplier Registration, 3: for End Users/ Customers.
/// </summary>
[Required(ErrorMessage = "User Type Field can't be empty")]
[Comment("The user type field to store the type of user 1: for BackOffice User , 2: for Supplier Registration, 3: for End Users/ Customers., 0: for Administrator")]
public Int16 UserType { get; set; }
[Required(ErrorMessage = "Password can't be empty")]
public string Password { get; set; }
[ValidateNever]
public string? returnUrl { get; set; }
}
}
View
#model RegisterVM
#{
ViewData["Title"] = "Register Page";
}
<form id="registrationForm" asp-controller="TestOPS" asp-action="Index" method="post">
<div class="card">
<div class="card-header">
<h5 class="card-title">
#{
#if (#Model.Mode == 1)
{
<b>Create</b>
}
else if (#Model.Mode == 2)
{
<b>Edit</b>
}
else if (#Model.Mode == 3)
{
<b>Delete</b>
}
}
</h5>
</div>
<div class="card-body">
<div class="row">
<div class="col-12">
<input type="hidden" id="hdnMode" asp-for="Mode" />
<input type="hidden" id="hdnUserId" asp-for="BOUser.UserId" />
</div>
</div>
<div class="row">
<div class="col-lg-2">
<label>First Name</label>
</div>
<div class="col-lg-4 form-group">
<input class="form-control form-control-sm" asp-for="#Model.BOUser.FirstName" name="firstname" />
<span asp-validation-for="BOUser.FirstName" class="text-danger"></span>
</div>
<div class="col-lg-2">
<label>Last Name</label>
</div>
<div class="col-lg-4 form-group">
<input class="form-control form-control-sm" asp-for="BOUser.LastName" name="lastname" />
<span asp-validation-for="BOUser.LastName" class="text-danger"></span>
</div>
</div>
<div class="row">
<div class="col-lg-2">
<label>Email</label>
</div>
<div class="col-lg-4 form-group">
<input class="form-control form-control-sm" asp-for="BOUser.Email" name="email" />
<span asp-validation-for="BOUser.Email" class="text-danger"></span>
</div>
<div class="col-lg-2">
<label>Phone No.</label>
</div>
<div class="col-lg-4 form-group">
<input class="form-control form-control-sm" asp-for="BOUser.PhoneNo" name="phoneno" />
<span asp-validation-for="BOUser.PhoneNo" class="text-danger"></span>
</div>
</div>
<div class="row">
<div class="col-lg-2">
<label>User Name</label>
</div>
<div class="col-lg-4 form-group">
<input class="form-control form-control-sm" asp-for="BOUser.UserName" name="username" />
<span asp-validation-for="BOUser.UserName" class="text-danger"></span>
</div>
</div>
<div class="row">
<div class="col-lg-2">
<label>Password</label>
</div>
<div class="col-lg-4 form-group">
<input class="form-control form-control-sm" asp-for="BOUser.Password" name="password" id="txtPassword" />
<span asp-validation-for="BOUser.Password" class="text-danger"></span>
</div>
</div>
<div class="row">
<div class="col-lg-2">
<label>Confirm Password</label>
</div>
<div class="col-lg-4 form-group">
<input class="form-control form-control-sm" name="confirmPassword" />
<span asp-validation-for="BOUser.Password" class="text-danger"></span>
</div>
</div>
<div class="row">
<div class="col-lg-2">
<label>Roles</label>
</div>
<div class="col-lg-5">
<table>
#if (Model.ApplicationRoles != null)
{
#foreach (var roles in Model.ApplicationRoles)
{
<tr>
<td>
<input id="#roles.Value" type="checkbox" name="roles" value="#roles.Value" checked="#roles.Selected" asp-for="#roles.Selected" />
</td>
<td>
<label asp-for="#roles.Value">#roles.Text</label>
</td>
</tr>
}
}
</table>
</div>
</div>
<div class="row">
<div class="col-lg-2">
<label>Department</label>
</div>
<div class="col-lg-5">
<table>
#if (Model.DepartmentMaster != null)
{
#foreach (var dept in Model.DepartmentMaster)
{
<tr>
<td>
<input id="#dept.Value" type="checkbox" name="departments" value="#dept.Value" checked="#dept.Selected" asp-for="#dept.Selected" />
</td>
<td>
<label asp-for="#dept.Value">#dept.Text</label>
</td>
</tr>
}
}
</table>
</div>
</div>
<div class="row">
<div class="col-lg-2">
<label>Approved</label>
</div>
<div class="col-lg-4">
<input type="checkbox" asp-for="BOUser.AccountConfirmed" />
</div>
</div>
</div>
<div class="card-footer text-right">
<input type="submit" class="btn btn-secondary" value="Save" />
</div>
</div>
</form>
#section Scripts{
<script src="~/js/regLogin.js"></script>
}
Debug Result
enter image description here

Remove a name attirbute from ALL web controls, for example should be just
<input class="form-control form-control-sm" asp-for="BOUser.LastName" />

Related

dotnet 5 MVC 404 error when I post to action

I have a page that is supposed to submit data for a patient evaluation. The page to submit the evaluation comes up fine. It is based on a ViewModel. Here is the ViewModel:
public class SPEPatientEvalVM
{
public int Id { get; set; }
public int ApptId { get; set; }
public int ActivityID { get; set; }
public int VendorID { get; set; }
public int PatientID { get; set; }
[Required(ErrorMessage ="A selection is required.")]
public int OverallRating { get; set; }
[Required(ErrorMessage = "A selection is required.")]
public int AppearProfessComp { get; set; }
[Required(ErrorMessage = "A selection is required.")]
public int EffGatheredInfo { get; set; }
[Required(ErrorMessage = "A selection is required.")]
public int ListenActively { get; set; }
[Required(ErrorMessage = "A selection is required.")]
public int EstabPersRapport { get; set; }
[Required(ErrorMessage = "A selection is required.")]
public int AppropExploreMyFeelings { get; set; }
[Required(ErrorMessage = "A selection is required.")]
public int AddressedMyFeelings { get; set; }
[Required(ErrorMessage = "A selection is required.")]
public int MetMyNeeds { get; set; }
public string PatientComments { get; set; } = String.Empty;
public DateTime DateSubmitted { get; set; }
}
This is mapped and reverse mapped to the model using IMapper.
Anyway this is my controller code:
[HttpGet("[controller]/[action]/{IDAppt}/{ActivityID}/{VendorID}/{PatientID}")]
public async Task<IActionResult> AddSPEPatientEval(int IDAppt, int ActivityID, int VendorID, int PatientID)
{
var patientChoice = GetPatientChoiceList();
patientChoice[0].Selected = true;
ViewBag.PatientChoice = patientChoice;
var evalParams = await _speRepo.GetOpenPatientEval(IDAppt);
ViewBag.Patient = evalParams.SPEPatient;
var speEval = new SPEPatientEvalVM
{
ApptId = IDAppt,
ActivityID = ActivityID,
VendorID = VendorID,
PatientID = PatientID
};
return View(speEval);
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> AddSPEPatientEval(SPEPatientEvalVM model)
{
var patientChoice = GetPatientChoiceList();
patientChoice[0].Selected = true;
ViewBag.PatientChoice = patientChoice;
model.DateSubmitted = DateTime.Now;
if (ModelState.IsValid)
{
var spePatientEval = _mapper.Map<SPEPatientEval>(model);
var success = await _speRepo.AddSPEPatientEval(spePatientEval);
if (!success)
{
return View(model);
}
return View("Index");
}
return View(model);
}
This is all for the form AddSPEPatientEval.cshtml
#model SPEPatientEvalVM
#{
ViewData["Title"] = "AddSPEPatientEval";
}
<div class="col-md-8 m-auto">
<h1 class="text-center">Patient SPE Evaluation</h1>
<hr />
</div>
<div class="col-md-8 m-auto">
<div class="row">
<div class="col-md-12">
<form asp-controller="SPE" asp-action="AddSPEPatientEval" method="post">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<input type="hidden" asp-for="ApptId" />
<input type="hidden" asp-for="ActivityID" />
<input type="hidden" asp-for="VendorID" />
<input type="hidden" asp-for="PatientID" />
<input type="hidden" asp-for="DateSubmitted" value="#String.Format("{0:MM/dd/yyyy}", DateTime.Now)" />
<div class="row">
<div class="col-md-8 m-auto">
<div class="form-group">
<label asp-for="OverallRating" class="control-label">As #ViewBag.Patient, rate your overall level of satisfaction with this encounter.</label>
<select asp-for="OverallRating" class="form-control"
asp-items="#(new SelectList(ViewBag.PatientChoice, "Value", "Text"))"></select>
<span asp-validation-for="OverallRating" class="text-danger"></span>
</div>
<br />
<hr />
</div>
</div>
<br />
<div class="row">
<div class="col-md-8 m-auto">
<div class="form-group">
<label asp-for="AppearProfessComp" class="control-label">Appeared professional competent - seemed to know what s/he was
doing; inspired my comfidence; appeared to have my interests at heart.
</b></label>
<select asp-for="AppearProfessComp" class="form-control"
asp-items="#(new SelectList(ViewBag.PatientChoice, "Value", "Text"))"></select>
<span asp-validation-for="AppearProfessComp" class="text-danger"></span>
</div>
</div>
</div>
<div class="row">
<div class="col-md-8 m-auto">
<div class="form-group">
<label asp-for="EffGatheredInfo" class="control-label">Effectively gathered information - collected information in a way that
seemed organized; began with several open-ended questions and progressed through interview using a balanced ratio of open-
to closed-ended questions; summarized periodically.
</label>
<select asp-for="EffGatheredInfo" class="form-control"
asp-items="#(new SelectList(ViewBag.PatientChoice, "Value", "Text"))"></select>
<span asp-validation-for="EffGatheredInfo" class="text-danger"></span>
</div>
</div>
</div>
<div class="row">
<div class="col-md-8 m-auto">
<div class="form-group">
<label asp-for="ListenActively" class="control-label">Listened actively - paid attention to both my verbal and non-verbal
cues; used facial expressions/body language to express encouragement; avoided interruptions; asked questions to make sure
s/he understood what I said.
</label>
<select asp-for="ListenActively" class="form-control"
asp-items="#(new SelectList(ViewBag.PatientChoice, "Value", "Text"))"></select>
<span asp-validation-for="ListenActively" class="text-danger"></span>
</div>
</div>
</div>
<div class="row">
<div class="col-md-8 m-auto">
<div class="form-group">
<label class="control-label">Established personal rapport - introduced self warmly; verbally/non-verbally showed interest
in me as a person, not just my condition; avoided technical jargon.
</label>
<select asp-for="EstabPersRapport" class="form-control"
asp-items="#(new SelectList(ViewBag.PatientChoice, "Value", "Text"))"></select>
<span asp-validation-for="EstabPersRapport" class="text-danger"></span>
</div>
</div>
</div>
<div class="row">
<div class="col-md-8 m-auto">
<div class="form-group">
<label asp-for="AppropExploreMyFeelings" class="control-label">Appropriately explored my perspective - encouraged me to
identify everything that I needed to say.
</label>
<select asp-for="AppropExploreMyFeelings" class="form-control"
asp-items="#(new SelectList(ViewBag.PatientChoice, "Value", "Text"))"></select>
<span asp-validation-for="AppropExploreMyFeelings" class="text-danger"></span>
</div>
</div>
</div>
<div class="row">
<div class="col-md-8 m-auto">
<div class="form-group">
<label asp-for="AddressedMyFeelings" class="control-label">Addressed my feelings - acknowledged and demonstrated interest in my
expressed and/orunexpressed feelings and experience.
</label>
<select asp-for="AddressedMyFeelings" class="form-control"
asp-items="#(new SelectList(ViewBag.PatientChoice, "Value", "Text"))"></select>
<span asp-validation-for="AddressedMyFeelings" class="text-danger"></span>
</div>
</div>
</div>
<div class="row">
<div class="col-md-8 m-auto">
<div class="form-group">
<label asp-for="MetMyNeeds" class="control-label">Met my needs - worked toward a plan which addressed both the diagnosis and
my concerns about my illness.
</label>
<select asp-for="MetMyNeeds" class="form-control"
asp-items="#(new SelectList(ViewBag.PatientChoice, "Value", "Text"))"></select>
<span asp-validation-for="MetMyNeeds" class="text-danger"></span>
</div>
</div>
</div>
<div class="row">
<div class="col-md-8 m-auto">
<div class="form-group">
<label asp-for="PatientComments" class="control-label"></label>
<textarea asp-for="PatientComments" class="form-control"
placeholder="Please add any additional comments you would like to express about this examination."></textarea>
</div>
</div>
</div>
<div class="row">
<div class="col-md-8 m-auto">
<div class="form-group">
<input type="submit" value="Submit" class="btn btn-primary" />
</div>
</div>
</div>
</form>
</div>
</div>
</div>
<div class="row">
<div class="col-md-8 m-auto">
<div class="text-center">
<a asp-action="Index">Back to List</a>
</div>
</div>
</div>
#section Scripts {
#{
await Html.RenderPartialAsync("_ValidationScriptsPartial");
}
}
Once the form is completed and all required fields are entered, if I hit the "Submit" button, I get:
This localhost page can’t be found
No webpage was found for the web
address:
https://localhost:5001/SPE/AddSPEPatientEval/18659/15129/235/4
HTTP ERROR 404
What am I missing guys? I am sure it is something that is in plain site. I am just have looked at it too long and cannot find what is going on.
What have I tried... I feel like everything. I have tried adding a route to the HttpPost statement. I have tried making sure all the model fields are not null. I do not know what else to try.
Thanks in advance for any help.
Your POST route should match the GET route:
[HttpPost("[controller]/[action]/{IDAppt}/{ActivityID}/{VendorID}/{PatientID}")]
Add [FromRoute] to the action parameters:
[HttpGet("[controller]/[action]/{IDAppt}/{ActivityID}/{VendorID}/{PatientID}")]
public async Task<IActionResult> AddSPEPatientEval([FromRoute]int IDAppt, [FromRoute] int ActivityID, [FromRoute] int VendorID, [FromRoute] int PatientID)
You should also change HttpGet to HttpPost.

ASP.NET Razor Pages ATM Credit Card funds check

I recently started learning Asp.Net with Razor Pages and I'm working on this project where users can enter his name last name and pin code for his credit card and if inputs are in the database, it redirects him to user page and shows him how much money he has on his card.
But my validation is wrong, even when input is not in the database or is different from values in the database it redirects me to User page.Can someone help me to make my validation right.
Thanks in advance.
Here is all my code:
Index page:
#page
#model BanlAcc.Pages.BankAcc.IndexModel
<br />
<h2 class="text-info">Enter your data</h2>
<div class=" border container" style="padding: 30px;">
<form method="post">
<div class="text-danger" asp-validation-summary="ModelOnly"></div>
<div class="form-group row">
<div class="col-3">
<label asp-for="Account.Name"></label>
</div>
<div class="col-6">
<input asp-for="Account.Name" class="form-control" />
</div>
</div>
<span class="text-danger" asp-validation-for="Account.Name"></span>
<div class="form-group row">
<div class="col-3">
<label asp-for="Account.Surname"></label>
</div>
<div class="col-6">
<input asp-for="Account.Surname" class="form-control" />
</div>
</div>
<span class="text-danger" asp-validation-for="Account.Surname"></span>
<div class="form-group row">
<div class="col-3">
<label asp-for="Account.Pin"></label>
</div>
<div class="col-6">
<input asp-for="Account.Pin" class="form-control" />
</div>
</div>
<span class="text-danger" asp-validation-for="Account.Pin"></span>
<div class="form-group row">
<div class="col-3">
<input type="submit" value="Check" class="btn btn-primary form-control" />
</div>
</div>
</form>
</div>
#section Scripts{
<partial name="_ValidationScriptsPartial" />
}
Index.cshtml.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using BanlAcc.Model;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;
namespace BanlAcc.Pages.BankAcc
{
public class IndexModel : PageModel
{
private readonly ApplicationDbContext _db;
private object _userRepository;
public IndexModel(ApplicationDbContext db)
{
_db = db;
}
[BindProperty]
public Account Account { get; set; }
public void OnGet()
{
}
public IActionResult OnPost()
{
if (ModelState.IsValid)
{
return RedirectToPage("User");
}
else
{
return Page();
}
}
}
}
Account.cs:
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading.Tasks;
namespace BanlAcc.Model
{
public class Account
{
[Key]
public int Id { get; set; }
[Required, MaxLength(20)]
public string Name { get; set; }
[Required, MaxLength(20)]
public string Surname { get; set; }
[Required]
public int Pin { get; set; }
public int Amount { get; set; }
}
}
User page:
#page
#model BanlAcc.Pages.BankAcc.AccountModel
<br />
<h2 class="text-info">Wellcome</h2>

Asp.net Core Razor Pages Unable to fetch value from csHTML to C#

Customer Model
public class CustomerModel
{
[Required]
public string FirstName { get; set; }
[Required]
public string LastName { get; set; }
[Required]
public string Contact { get; set; }
[Required]
public int Notifications { get; set; }
[Required]
public int InfoCollect { get; set; }
[Required]
public string Email { get; set; }
public UserModel User { get; set; }
}
UserModel Class
public class UserModel
{
[Key]
[Required]
public string Email { get; set; }
[Required]
public string Password { get; set; }
[Required]
public string AccountType { get; set; }
}
}
Data Context
public class OnlineFoodOrderingWebApplicationContext : DbContext
{
public OnlineFoodOrderingWebApplicationContext (DbContextOptions<OnlineFoodOrderingWebApplicationContext> options)
: base(options)
{
}
public DbSet<OnlineFoodOrderingWebApplication.Models.UserModel> NewUser { get; set; }
public DbSet<OnlineFoodOrderingWebApplication.Models.CustomerModel> Customer { get; set; }
public DbSet<OnlineFoodOrderingWebApplication.Models.StaffModel> Staff { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder
.Entity<CustomerModel>(eb =>
{
eb.HasNoKey();
});
modelBuilder
.Entity<StaffModel>(eb =>
{
eb.HasNoKey();
});
}
}
Register Page HTML
<div class="form-group">
<div class="form-row">
<div class="col-md-6">
<div class="form-label-group">
<input name="firstName" type="text" class="form-control" placeholder="First name" required="required" asp-for="Customer.FirstName" />
<label for="firstName">First name</label>
</div>
</div>
<div class="col-md-6">
<div class="form-label-group">
<input type="text" name="lastName" class="form-control" placeholder="Last name" required="required" asp-for="Customer.LastName" />
<label for="lastName">Last name</label>
</div>
</div>
</div>
</div>
<div class="form-group">
<div class="form-label-group">
<input type="email" name="inputEmail" class="form-control" placeholder="Email address" required="required" asp-for="NewUser.Email" />
<label for="inputEmail">Email address</label>
</div>
</div>
<div class="form-group">
<div class="form-label-group">
<input type="text" name="inputContact" asp-for="Customer.Contact" class="form-control" placeholder="Contact Number" required="required" />
<label for="inputContact">Contact Number</label>
</div>
</div>
<div class="form-group">
<div class="form-row">
<div class="col-md-6">
<div class="form-label-group">
<input type="password" name="inputPassword" asp-for="NewUser.Password" class="form-control" placeholder="Password" required="required" />
<label for="inputPassword">Password</label>
</div>
</div>
<div class="col-md-6">
<div class="form-label-group">
<input type="password" name="confirmPassword" class="form-control" placeholder="Confirm password" required="required" />
<label for="confirmPassword">Confirm password</label>
</div>
</div>
</div>
</div>
#if (!ViewData.ModelState.IsValid && ViewData.ModelState["Error"].Errors.Count > 0)
{
<div class="alert alert-
<strong>Error!</strong> danger">#ViewData.ModelState["Error"].Errors.First().ErrorMessage
</div>
}
<button class="btn btn-primary btn-block" type="submit"> Send Message</button>
Register Page html.cs
public class RegisterModel : PageModel
{
private readonly ILogger<IndexModel> _logger;
private readonly OnlineFoodOrderingWebApplication.Data.OnlineFoodOrderingWebApplicationContext _context;
public RegisterModel(OnlineFoodOrderingWebApplication.Data.OnlineFoodOrderingWebApplicationContext context, ILogger<IndexModel> logger)
{
_context = context;
_logger = logger;
}
public void OnGet()
{
}
public IActionResult Create()
{
return Page();
}
[BindProperty]
public CustomerModel Customer { get; set; }
[BindProperty]
public UserModel NewUser { get; set; }
public IActionResult OnPost()
{
if (ModelState.IsValid == false)
{
NewUser.AccountType = "Customer";
ModelState.AddModelError("Error", "This is Error"+ NewUser.AccountType+ NewUser.Password+Customer.LastName);
return Page();
}
Customer.Notifications = 1;
Customer.InfoCollect = 1;
_context.NewUser.Add(NewUser);
return RedirectToPage("/Index");
}
}
There is a bug that i unable to fetch the "NewUser" data from html input to the OnPost Method.
However, that seems to be the same with "Customer" but the "Customer" has worked well that able to get the data from the input.
In order to make your OnPost method catch your html input parameters you have to wrap them inside the form tag. So your Register Page Html must look like that:
<form method="post">
<div class="form-group">
<div class="form-row">
<div class="col-md-6">
<div class="form-label-group">
<input name="firstName" type="text" class="form-control" placeholder="First name" required="required" asp-for="Customer.FirstName" />
<label for="firstName">First name</label>
</div>
</div>
<div class="col-md-6">
<div class="form-label-group">
<input type="text" name="lastName" class="form-control" placeholder="Last name" required="required" asp-for="Customer.LastName" />
<label for="lastName">Last name</label>
</div>
</div>
</div>
</div>
<div class="form-group">
<div class="form-label-group">
<input type="email" name="inputEmail" class="form-control" placeholder="Email address" required="required" asp-for="NewUser.Email" />
<label for="inputEmail">Email address</label>
</div>
</div>
<div class="form-group">
<div class="form-label-group">
<input type="text" name="inputContact" asp-for="Customer.Contact" class="form-control" placeholder="Contact Number" required="required" />
<label for="inputContact">Contact Number</label>
</div>
</div>
<div class="form-group">
<div class="form-row">
<div class="col-md-6">
<div class="form-label-group">
<input type="password" name="inputPassword" asp-for="NewUser.Password" class="form-control" placeholder="Password" required="required" />
<label for="inputPassword">Password</label>
</div>
</div>
<div class="col-md-6">
<div class="form-label-group">
<input type="password" name="confirmPassword" class="form-control" placeholder="Confirm password" required="required" />
<label for="confirmPassword">Confirm password</label>
</div>
</div>
</div>
</div>
#if (!ViewData.ModelState.IsValid && ViewData.ModelState["Error"].Errors.Count > 0)
{
<div class="alert alert-
<strong>Error!</strong> danger">#ViewData.ModelState["Error"].Errors.First().ErrorMessage
</div>
}
<button class="btn btn-primary btn-block" type="submit"> Send Message</button>
</form>

Why would a bool value not be displaying in view correctly?

I have a bool value that I'm using to distinguish between the first item in a series of other items being saved to a link table in my DB. The constructor for the ViewModel sets this to true by default. When my ViewModel is posted to the controller my controller action changes this value to false and passes the edited ViewModel back to the View where this value is saved in a hidden field.
The issue I have is that after the value has been changed, my View is still displaying this value as true. Does anyone have any idea where I'm going wrong?
I also have an issue where I reset the values back to default but these are being retained when the view is reloaded after the post action in executed.
ViewModel
public class NewScriptViewModel
{
public Patient Patient { get; set; }
public int PatientId { get; set; }
public int PrescriberId { get; set; }
public int DrugId { get; set; }
public int Qty { get; set; }
public string Directions { get; set; }
public bool FirstItem { get; set; }
public bool NextItem { get; set; }
public int ScriptId { get; set; }
public NewScriptViewModel()
{
FirstItem = true;
NextItem = false;
}
}
View
#model DispensingApp.Models.ViewModels.NewScriptViewModel
#{
ViewData["Title"] = "New Script";
}
<h1>#Model.Patient.FullName</h1>
<h3>HCN : #Model.Patient.HCN</h3>
<hr />
<div class="row">
<br />
<div class="col-12" onload="newScriptItemForm.reset()">
<form id="newScriptItemForm" asp-action="Create">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<input asp-for="ScriptId" type="hidden" value="#ViewData["ScriptId"]" />
<input asp-for="DrugId" type="hidden" />
<table id="drugSelectionTable" class="table table-hover">
<thead>
<tr class="table-secondary">
<th></th>
<th>Name</th>
<th>Pack Size</th>
<th>Generic Ingredients</th>
<th>Stock</th>
</tr>
</thead>
</table>
<div class="form-group">
<div><input asp-for="PatientId" type="hidden" /></div>
</div>
<div class="form-group row">
<div class="col-2">
<label asp-for="Patient.Prescriber.FullName" class="control-label"></label>
</div>
<div class="col-4">
#if (Model.FirstItem)
{
<select asp-for="PrescriberId" class="form-control" asp-items="ViewBag.PrescriberId"></select>
}
else
{
<input asp-for="PrescriberId" type="hidden" />
<input type="text" placeholder="#Model.PrescriberId" class="disabled" />
}
</div>
</div>
<div class="form-group row">
<div class="col-2">
<label asp-for="Qty" class="control-label"></label>
</div>
<div class="col-4">
<input asp-for="Qty" class="form-control" />
</div>
<span asp-validation-for="Qty" class="text-danger"></span>
</div>
<div class="form-group row">
<div class="col-2">
<label asp-for="Directions" class="control-label"></label>
</div>
<div class="col-4">
<textarea asp-for="Directions" rows="3" class="form-control"></textarea>
</div>
<span asp-validation-for="Directions" class="text-danger"></span>
</div>
<div class="form-group row">
<div class="col-2">
<input asp-for="FirstItem" type="hidden" />
<input id="nextItem" asp-for="NextItem" type="hidden" />
<button id="nextItemBtn" #*type="submit" value="Next Item"*# class="btn btn-primary form-control">Next Item</button>
</div>
<div class="col-2">
<button asp-action="NewScript" class="btn btn-success form-control">Next Script</button>
</div>
<div class="col-2">
<a asp-controller="Patients" asp-action="Details" asp-route-id="#Model.PatientId" class="btn btn-danger form-control">Cancel</a>
</div>
</div>
</form>
</div>
</div>
Controller Post
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create(NewScriptViewModel viewModel,
[Bind("PatientId, PrescriberId")] Script script,
[Bind("DrugId, Qty, Directions")] ScriptDrug scriptDrug)
{
if (ModelState.IsValid)
{
//if first item of script -- create script entry
if (viewModel.FirstItem)
{
_context.Script.Add(script);
await _context.SaveChangesAsync();
viewModel.ScriptId = script.Id;
viewModel.FirstItem = false;
}
scriptDrug.ScriptId = (int)viewModel.ScriptId;
var drug = _context.Drug.Find(scriptDrug.DrugId);
drug.StockQty -= scriptDrug.Qty;
_context.ScriptDrug.Add(scriptDrug);
await _context.SaveChangesAsync();
return await Create(script.PatientId, viewModel);
}
viewModel.NextItem = false;
return await Create(script.PatientId, viewModel);
}
Controller Get
public async Task<IActionResult> Create(int id, NewScriptViewModel viewModel)
{
var patient = await _context.Patient.FindAsync(id);
var vm = new NewScriptViewModel();
//if not first item, reset view model but retain script id
if (!viewModel.FirstItem)
{
vm = viewModel;
}
vm.Patient = patient;
vm.PatientId = patient.Id;
return View(vm);
}
The HTML that is rendered to the browser after all of this looks like:
<div class="col-2">
<input type="hidden" data-val="true" data-val-required="The FirstItem field is required." id="FirstItem" name="FirstItem" value="True">
<input id="nextItem" type="hidden" data-val="true" data-val-required="The NextItem field is required." name="NextItem" value="True">
<button id="nextItemBtn" class="btn btn-primary form-control">Next Item</button>
</div>

asp.net scaffolded generate item - select tag without options from database

I try to reinterpretate [this simple tutorial][1]
In Book model I remove ScaffoldColumn(false) above public int AuthorID to have select AuthorID in my view.
After rebiuld I can see this select in Books/Create but it has no options.
In my database I can see, that all my items added in SampleData model has BookID and AuthorID.
Why it has no result in html ?
Edited:
My Book.cs
using System.ComponentModel.DataAnnotations;
namespace ContosoBooks.Models
{
public class Book
{
public int BookID { get; set; }
[Required]
public string Title { get; set; }
public int Year { get; set; }
[Range(1, 500)]
public decimal Price { get; set; }
public string Genre { get; set; }
public int AuthorID { get; set; }
// Navigation property
public virtual Author Author { get; set; }
}
}
My Author.cs
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
namespace ContosoBooks.Models
{
public class Author
{
public int AuthorID { get; set; }
[Required]
[Display(Name = "Last Name")]
public string LastName { get; set; }
[Display(Name = "First Name")]
public string FirstMidName { get; set; }
public virtual ICollection<Book> Books { get; set; }
}
}
My Scaffolded generated View for Books Create (Create.cshtml)
#model ContosoBooks.Models.Book
#{
ViewData["Title"] = "Create";
}
<h2>Create</h2>
<form asp-action="Create">
<div class="form-horizontal">
<h4>Book</h4>
<hr />
<div asp-validation-summary="ValidationSummary.ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="AuthorID" class="col-md-2 control-label"></label>
<div class="col-md-10">
<select asp-for="AuthorID" class ="form-control"></select>
</div>
</div>
<div class="form-group">
<label asp-for="Genre" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="Genre" class="form-control" />
<span asp-validation-for="Genre" class="text-danger" />
</div>
</div>
<div class="form-group">
<label asp-for="Price" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="Price" class="form-control" />
<span asp-validation-for="Price" class="text-danger" />
</div>
</div>
<div class="form-group">
<label asp-for="Title" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="Title" class="form-control" />
<span asp-validation-for="Title" class="text-danger" />
</div>
</div>
<div class="form-group">
<label asp-for="Year" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="Year" class="form-control" />
<span asp-validation-for="Year" class="text-danger" />
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
</form>
<div>
<a asp-action="Index">Back to List</a>
</div>
#section Scripts {
<script src="~/lib/jquery/dist/jquery.min.js"></script>
<script src="~/lib/jquery-validation/dist/jquery.validate.min.js"></script>
<script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"></script>
}
[1]: http://docs.asp.net/en/latest/tutorials/your-first-aspnet-application.html
On your create page it won't display the ID because it has no value and the application is anticipating the ID will be generated when the object is inserted into the database.

Categories

Resources