Adding Dropdown to Register.cshtml in Identity - asp.net-core-mvc

I am using Microsoft Identity in my Asp.NET MVC Core 7.0 application with a customized IdentityUser:
public class SparkleWebAppUser : IdentityUser
{
[Required(ErrorMessage = "Must provide a user name")]
[StringLength(15, ErrorMessage = "User name cannot be longer than 15 letters")]
[Display(Name = "User Name")]
public override string UserName { get; set; } = string.Empty;
[Required(ErrorMessage = "Must provide first name")]
[StringLength(20, ErrorMessage = "First name cannot be longetr than 20 letters")]
public string FirstName { get; set; } = string.Empty;
[Required(ErrorMessage = "Must provide last name")]
[StringLength(20, ErrorMessage = "First name cannot be longer than 20 letters")]
public string LastName { get; set; } = string.Empty;
[Required(ErrorMessage = "Must provide a parent id to continue. Please contact your company/organisation to get parents id.")]
[Display(Name = "Your Organization's ID")]
public int OrgId { get; set; }
[Required(ErrorMessage = "Must mention type of application user")]
//[ForeignKey("UserType")]
public AppUserType AppUserType { get; set; }
[NotMapped]
public IEnumerable<AppUserType> SelectedAppUserType { get; set; }
public virtual WorkLocation? OfficeName { get; set; }
[Required(ErrorMessage = "Must provide Id Number provided to you by your organization")]
[DataType(DataType.Text)]
[Display(Name = "Your personal ID in the organization")]
public string IdNumber { get; set; } = string.Empty;
[Display(Name = "Profile Picture")]
public byte[]? ProfilePic { get; set; }
[Display(Name = "Full Name")]
[NotMapped]
public string FullName { get { return (FirstName + " " + LastName); } }
}
below is the model of AppUserType:
public class AppUserType
{
[Key]
[ScaffoldColumn(false)]
public int Id { get; set; }
[Required]
[StringLength(15, ErrorMessage = "Name cannot be longer than 15 letters")]
[Display(Name = "User Type Name")]
public string Name { get; set; } = String.Empty;
[Display(Name = "App Users")]
public ICollection<SparkleWebAppUser>? lIMISAppUsers { get; set; }
}
The Register in Identity is given below:
#page
#using iStar.Sparkle.WebDev.Areas.Identity.Models;
#model RegisterModel
#{
ViewData["Title"] = "New User Sign Up";
//Layout = "~/Areas/Identity/Views/Shared/_IdentityLayout.cshtml";
}
<h1>#ViewData["Title"]</h1>
<div class="row">
<div class="col-md-4">
<form id="registerForm" asp-route-returnUrl="#Model.ReturnUrl" method="post">
<h2>Create a new account.</h2>
<hr />
<div asp-validation-summary="ModelOnly" class="text-danger" role="alert"></div>
<div class="form-floating mb-3">
<input asp-for="Input.UserName" class="form-control" autocomplete="on" aria-required="true" placeholder="name#example.com" />
<label asp-for="Input.UserName">User Name</label>
<span asp-validation-for="Input.UserName" class="text-danger"></span>
</div>
<div class="form-floating mb-3">
<input asp-for="Input.FirstName" class="form-control" autocomplete="on" aria-required="true" placeholder="name#example.com" />
<label asp-for="Input.FirstName">First Name</label>
<span asp-validation-for="Input.FirstName" class="text-danger"></span>
</div>
<div class="form-floating mb-3">
<input asp-for="Input.LastName" class="form-control" autocomplete="on" aria-required="true" placeholder="name#example.com" />
<label asp-for="Input.LastName">Last Name</label>
<span asp-validation-for="Input.LastName" class="text-danger"></span>
</div>
<div class="form-floating mb-3">
<input asp-for="Input.OrgId" class="form-control" autocomplete="on" aria-required="true" placeholder="name#example.com" />
<label asp-for="Input.OrgId">Company ID</label>
<span asp-validation-for="Input.OrgId" class="text-danger"></span>
</div>
<div class="form-floating mb-3">
<input asp-for="Input.OfficeName" class="form-control" autocomplete="on" aria-required="true" placeholder="name#example.com" />
<label asp-for="Input.OfficeName">Company's Office Name</label>
<span asp-validation-for="Input.OfficeName" class="text-danger"></span>
</div>
#* <div class="form-floating mb-3">
<input asp-for="Input.AppUserType" class="form-control" autocomplete="on" aria-required="true" placeholder="name#example.com" />
<label asp-for="Input.AppUserType">Access Type</label>
<span asp-validation-for="Input.AppUserType" class="text-danger"></span>
</div>*#
<div class="form-group mb-3">
#*<select asp-for="Input.AppUserType" asp-items="#(new SelectList(AppUserType, "Id", "Name"))" value="Id">Access Type</select>*#
#*<input asp-for="Input.AppUserType" class="form-control" autocomplete="on" aria-required="true" placeholder="name#example.com" />*#
<label asp-for="Input.AppUserType">Access Type</label>
<span asp-validation-for="Input.AppUserType" class="text-danger"></span>
</div>
<div class="form-floating mb-3">
<input asp-for="Input.Email" class="form-control" autocomplete="on" aria-required="true" placeholder="name#example.com" />
<label asp-for="Input.Email">Email</label>
<span asp-validation-for="Input.Email" class="text-danger"></span>
</div>
<div class="form-floating mb-3">
<input asp-for="Input.Password" class="form-control" autocomplete="new-password" aria-required="true" placeholder="password" />
<label asp-for="Input.Password">Password</label>
<span asp-validation-for="Input.Password" class="text-danger"></span>
</div>
<div class="form-floating mb-3">
<input asp-for="Input.ConfirmPassword" class="form-control" autocomplete="new-password" aria-required="true" placeholder="password" />
<label asp-for="Input.ConfirmPassword">Confirm Password</label>
<span asp-validation-for="Input.ConfirmPassword" class="text-danger"></span>
</div>
<button id="registerSubmit" type="submit" class="w-100 btn btn-lg btn-primary">Register</button>
</form>
</div>
<div class="col-md-6 col-md-offset-2">
<section>
<h3>Use another service to register.</h3>
<hr />
#{
if ((Model.ExternalLogins?.Count ?? 0) == 0)
{
<div>
<p>
There are no external authentication services configured. See this <a href="https://go.microsoft.com/fwlink/?LinkID=532715">article
about setting up this ASP.NET application to support logging in via external services</a>.
</p>
</div>
}
else
{
<form id="external-account" asp-page="./ExternalLogin" asp-route-returnUrl="#Model.ReturnUrl" method="post" class="form-horizontal">
<div>
<p>
#foreach (var provider in Model.ExternalLogins!)
{
<button type="submit" class="btn btn-primary" name="provider" value="#provider.Name" title="Log in using your #provider.DisplayName account">#provider.DisplayName</button>
}
</p>
</div>
</form>
}
}
</section>
</div>
</div>
#section Scripts {
<partial name="_ValidationScriptsPartial" />
}
I want to use a drop down SelectItemList for AppUserType in the Register page. I have tried several ways but none is working. The last one mentioned here
<div class="form-group mb-3">
<select asp-for="Input.AppUserType" asp-items="#(new SelectList(AppUserType, "Id", "Name"))" value="Id">Access Type</select>
#*<input asp-for="Input.AppUserType" class="form-control" autocomplete="on" aria-required="true" placeholder="name#example.com" />*#
<label asp-for="Input.AppUserType">Access Type</label>
<span asp-validation-for="Input.AppUserType" class="text-danger"></span>
</div>
looks quite sensible but I don't know how can I fill the drop down from table 'AppUserTypes' in this dropdown.

Is your dropdown's value from a database table?
You can try to create a property into the RegisterModel:
[BindProperty]
public SelectList DropDown { get; set; }
public async Task OnGetAsync(string returnUrl = null)
{
DropDown = new SelectList(_context.AppUserType.ToList(),"Id","Name");
//...
}
And in Register.cshtml:
<div class="form-group mb-3">
<select asp-for="Input.AppUserType" aria-required="true" asp-items="#Model.DropDown" value="Id">Access Type</select>
#*<input asp-for="Input.AppUserType" class="form-control" autocomplete="on" aria-required="true" placeholder="name#example.com" />*#
<label asp-for="Input.AppUserType">Access Type</label>
<span asp-validation-for="Input.AppUserType" class="text-danger"></span>
</div>

Related

How to update value progress bar bootstrap from controller in ASP .NET Core

I have a table that receive email of my users for newsletter .I Show it on my dashboard with count .but now I want to show on progress bar and its percentage per last month
how do I do ? I create another view model for show count of some things
I can show count of them but I need show on progress bar too.
my viewmodel:
public class NewsLetterViewModel
{
public string Phone { get; set; }
public string Email { get; set; }
public DateTime CreateDate { get; set; }
}
You can try to use ViewBag to pass count and percentage.Here is a demo:
Action:
public IActionResult News()
{
ViewBag.Count = 0;
ViewBag.Percentage = 0;
return View();
}
[HttpPost]
public IActionResult News(NewsLetterViewModel n,int Count)
{
//you can pass the count and percentage with ViewBag here
ViewBag.Count= Count+ 1;
ViewBag.Percentage=25;
return View();
}
View:
<div>
Count:#ViewBag.Count
</div>
<div class="progress">
<div class="progress-bar" role="progressbar" style="width: #ViewBag.Percentage%;" aria-valuenow="#ViewBag.Percentage" aria-valuemin="0" aria-valuemax="100">#ViewBag.Percentage%</div>
</div>
<form method="post">
<input hidden name="Count" value="#ViewBag.Count" />
<div class="form-group">
<label asp-for="Phone" class="control-label"></label>
<input asp-for="Phone" class="form-control" />
<span asp-validation-for="Phone" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Email" class="control-label"></label>
<input asp-for="Email" class="form-control" />
<span asp-validation-for="Email" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="CreateDate" class="control-label"></label>
<input asp-for="CreateDate" class="form-control" />
<span asp-validation-for="CreateDate" class="text-danger"></span>
</div>
<input type="submit"value="submit" />
</form>
result:

How can I store records in a list request from an HttpPost

How can I store records in a list from an HttpPost request that sends an object
I want to store each record that it processes again from the view
Take the _students object and send it to a list:
List dbTempStudentList
To work locally with data and not depend on a database
[HttpPost]public ActionResult Create(Student _student)
{
return View("");
}
public class Student
{
public int StudentID { get; set; }
public string StudentName { get; set; }
public string StudentLastName { get; set; }
public string Creditbalance { get; set; }
public string CurrentBalance { get; set; }
}
My View Create
<h2>Create</h2>
<h4>Student</h4>
<hr />
<div class="row">
<div class="col-md-4">
<form asp-action="Create" method="post">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="StudentID" class="control-label"></label>
<input asp-for="StudentID" class="form-control" />
<span asp-validation-for="StudentID" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="StudentName" class="control-label"></label>
<input asp-for="StudentName" class="form-control" />
<span asp-validation-for="StudentName" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="StudentLastName" class="control-label"></label>
<input asp-for="StudentLastName" class="form-control" />
<span asp-validation-for="StudentLastName" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Creditbalance" class="control-label"></label>
<input asp-for="Creditbalance" class="form-control" />
<span asp-validation-for="Creditbalance" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="CurrentBalance" class="control-label"></label>
<input asp-for="CurrentBalance" class="form-control" />
<span asp-validation-for="CurrentBalance" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</form>
</div>
</div>
[HttpPost]
public ActionResult Create(Student _student)
{
var list = (List<Student>)Session["studentList"];
//this is for first time
if(list==null||list.Count()==0) list = new List<Student>();
list.Add(_student);
Session["studentList"]=list;
return View();
}

Asp-validation-summary="ModelOnly" does not work for compare data-validator

View Does displays Span validation but Validation summary(blank validation-summary div also not present).if i change Asp-validation-summary="All".I am not getting why it is not working with ModelOnly.
My Class
public class RegistrationViewModel
{
[Required]
[EmailAddress]
[MinLength(5)]
public string Email { get; set; }
[Required]
[DataType(DataType.Password)]
public string Password { get; set; }
[Required]
[DataType(DataType.Password)]
[Compare("Password")]
[Display(Name = "Confirm Password")]
public string VerifiedPassword { get; set; }
}
view
<form asp-action="Registration">
<div asp-validation-summary="ModelOnly" val class="text-danger"></div>
<div class="form-group">
<label asp-for="Email" class="control-label"></label>
<input asp-for="Email" class="form-control" />
<span asp-validation-for="Email" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Password" class="control-label"></label>
<input asp-for="Password" class="form-control" required />
<span asp-validation-for="Password" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="VerifiedPassword" class="control-label"></label>
<input asp-for="VerifiedPassword" class="form-control" required/>
#*<span asp-validation-for="VerifiedPassword" class="text-danger"></span>*#
</div>
<div class="form-group">
<input type="submit" value="Register" class="btn btn-default" />
</div>
</form>
Add this to post method in the controller:
if (!ModelState.IsValid)
{
AddErrorsFromModel(ModelState.Values);
return View();
}
Also add using and AddErrorsFromModel to controller:
using Microsoft.AspNetCore.Mvc.ModelBinding;
private void AddErrorsFromModel(ModelStateDictionary.ValueEnumerable values)
{
foreach (ModelStateEntry modelState in values)
foreach (ModelError error in modelState.Errors)
{
ModelState.AddModelError(string.Empty, error.ErrorMessage.ToString());
}
}

ASP.NET Core model binding

I'm trying to bind an edit action to a model which doesn't work. Here below the controller:
[Route("[controller]/[action]")]
public class CustomerController : Controller
{
private readonly IUnitOfWork _unitOfWork;
public CustomerController(IUnitOfWork unitOfWork)
{
_unitOfWork = unitOfWork;
}
[HttpGet("{_customerCode}")]
public IActionResult Edit(int _customerCode)
{
var customer = _unitOfWork.Customers.getCustomerByCode(_customerCode);
var customerDTO = Mapper.Map<CustomerModelDTO>(customer);
return View(customerDTO);
}
[HttpPost]
public IActionResult Edit(CustomerModelDTO model)
{
if (!ModelState.IsValid)
{
return View(model);
}
var _customer = _unitOfWork.Customers.getCustomerByCode(model.CustomerCode);
if (_customer==null)
{
return NotFound();
}
Mapper.Map(model, _customer);
_unitOfWork.Complete();
return RedirectToAction("Detail", new { customerCode = _customer.CustomerCode });
}
}
And here is the view I am using:
#model Almiz.Dtos.CustomerModelDTO
<form asp-action="Edit" method="post">
<div class="form-horizontal">
<h4>CustomerModelDTO</h4>
<hr />
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="CustomerCode" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="CustomerCode" class="form-control" />
<span asp-validation-for="CustomerCode" class="text-danger" />
</div>
</div>
<div class="form-group">
<label asp-for="FirstName" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="FirstName" class="form-control" />
<span asp-validation-for="FirstName" class="text-danger" />
</div>
</div>
<div class="form-group">
<label asp-for="MiddleName" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="MiddleName" class="form-control" />
<span asp-validation-for="MiddleName" class="text-danger" />
</div>
</div>
<div class="form-group">
<label asp-for="LastName" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="LastName" class="form-control" />
<span asp-validation-for="LastName" class="text-danger" />
</div>
</div>
<div class="form-group">
<label asp-for="Telephone" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="Telephone" class="form-control" />
<span asp-validation-for="Telephone" class="text-danger" />
</div>
</div>
<div class="form-group">
<label asp-for="Mobile" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="Mobile" class="form-control" />
<span asp-validation-for="Mobile" class="text-danger" />
</div>
</div>
<div class="form-group">
<label asp-for="Email" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="Email" class="form-control" />
<span asp-validation-for="Email" class="text-danger" />
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-default" />
</div>
</div>
</div>
</form>
<div>
<a asp-action="Index">Back to Index</a>
</div>
#section Scripts {
#{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}
When I call the view and with the ID http://localhost:65001/Customer/Edit/1001, I get the all the information. However when I edit it and post the edited form I get resource not found error. Please help. Here below the model:
public class CustomerModelDTO
{
public int CustomerCode { get; set; }
public string FirstName { get; set; }
public string MiddleName { get; set; }
public string LastName { get; set; }
public double Telephone { get; set; }
public double Mobile { get; set; }
public string Email { get; set; }
}
I got it working. Here below the change.
[HttpPost("{customerCode}")]
public IActionResult Edit(int customerCode, CustomerModelDTO data)

Display Friendly Error Message When using Decorators in Models

New to ASP.NET Core.
I have a view:
<form asp-action="LogIn">
<div class="form-horizontal">
<hr />
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="EmailAddress" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="EmailAddress" class="form-control" style="min-width:350px" />
<span asp-validation-for="EmailAddress" class="text-danger"></span>
</div>
</div>
<div class="form-group">
<label asp-for="Password" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="Password" class="form-control" style="min-width:350px" />
<span asp-validation-for="Password" class="text-danger"></span>
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Enter" class="btn btn-default" />
</div>
</div>
</div>
</form>
I have this Model for it:
public class Subscription
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public long SubscriptionId { get; set; }
[Display(Name = "Email Address")]
[Required]
[RegularExpression(#"\w+([-+.']\w+)*#\w+([-.]\w+)*\.\w+([-.]\w+)*")]
public string EmailAddress { get; set; }
[NotMapped]
public string Password { get; set; }
}
So, when a User types in an email address that is not validated by the regular expression I get the error message:
How do i over-ride this 'default' error message to say (for example):
Email Address is Invalid
?
You need to add ErrorMessage property to the RegularExpression attribute like this-
[RegularExpression(#"\w+([-+.']\w+)*#\w+([-.]\w+)*\.\w+([-.]\w+)*", ErrorMessage = "Your friendly message goes here")]

Resources