Cannot update user Identity Role from list in razor page - asp.net-core

I have a razor page which shows checkbox of Roles. The Roles owned by the selected user will be checked on page load. What I'm trying to do is, I want to be able to edit the roles for the selected user. But when I click update, it doesn't update.
Here is the razor page:
<EditForm Model="#RoleDto" OnValidSubmit="#EditRole">
<DataAnnotationsValidator />
<ValidationSummary />
<div class="card">
<div class="card-header">
<h2>Manage User Roles</h2>
Add/Remove Roles for User / #UserFullname
</div>
<div class="card-body">
#for (int i = 0; i < numOfRoles; i++)
{
<div class="form-check m-1">
<input type="hidden" value="#RoleListModel[i].Id" />
<input type="hidden" value="#RoleListModel[i].Name" />
<input type="checkbox" checked="#RoleListModel[i].Selected" /> #RoleListModel[i].Name
</div>
}
</div>
</div>
<button type="submit" class="btn btn-success btn-block">
Confirm
</button>
#code {
ApplicationRoleDto RoleDto = new ApplicationRoleDto();
private List<ApplicationRoleDto> RoleListModel;
[Parameter] public string Id { get; set; }
[Parameter] public ApplicationUserDto UserDto { get; set; }
[Parameter] public string UserFullname { get; set; }
[Parameter] public int numOfRoles { get; set; }
protected async override Task OnParametersSetAsync()
{
UserDto = await _client.GetFromJsonAsync<ApplicationUserDto>($"api/userroles/{Id}");
UserFullname = UserDto.FullName;
RoleListModel = await _client.GetFromJsonAsync<List<ApplicationRoleDto>>($"api/rolemanager/{Id}");
numOfRoles = RoleListModel.Count();
}
async Task EditRole()
{
await _client.PostAsJsonAsync($"api/rolemanager/{Id}", RoleListModel);
_navManager.NavigateTo($"/userroles/");
}
}
and here is the controller:
[HttpPost]
public async Task<IActionResult> Manage(List<ApplicationRoleDto> model, string Id)
{
var user = await _userManager.FindByIdAsync(Id);
if (user == null)
{
NotFound();
}
var roles = await _userManager.GetRolesAsync(user);
var result = await _userManager.RemoveFromRolesAsync(user, roles);
if (!result.Succeeded)
{
Console.WriteLine("Cannot remove user existing roles");
return NotFound();
}
result = await _userManager.AddToRolesAsync(user, model.Where(x => x.Selected).Select(y => y.Name));
if (!result.Succeeded)
{
Console.WriteLine("Cannot add selected roles to user");
return NotFound();
}
return NoContent();
}
Did I miss anything here?

Related

Properties set to null when OnPost handler is called in razor page

I have a page with 2 buttons each one with their handler methods (OnPostAsync and OnPostResend) and 2 properties (LoginType and DocumentNumber) when OnPostAsync is called, properties have their values and the method works as expected but when the second button is clicked and OnPostResend is called properties are set to null. Why is this happenning and how can I prevent it?
This is the .cshtml file:
#page
#model SATCloudWebApp.Areas.Identity.Pages.Account.EnterOtpModel
#{
ViewData["Title"] = $"Ingrese el código de confirmación";
string device = TempData["PhoneNumber"]
}
}
<h2>#ViewData["Title"]</h2>
<div class="row">
<div class="col-md-6">
<h4>Por favor digite el código enviado a su #device. </h4>
<form method="post">
<div asp-validation-summary="All" class="text-danger"></div>
<div class="form-group">
<label asp-for="Input.OtpCode"></label>
<input asp-for="Input.OtpCode" class="form-control" />
<span asp-validation-for="Input.OtpCode" class="text-danger"></span>
</div>
<button type="submit" class="btn btn-info">Siguiente</button>
</form>
<href>
<form asp-page-handler="resend" method="post">
<button id="resendToken" type="submit" class="btn btn-dark">Reenviar código</button>
</form>
</href>
</div>
</div>
This is the page model:
namespace Name
{
[AllowAnonymous]
public class EnterOtpModel : PageModel
{
// constructor goes here ...
[BindProperty]
public string LoginType { get; set; }
[BindProperty]
public string DocumentNumber { get; set; }
[BindProperty]
public InputModel Input { get; set; }
public class InputModel
{
[Required(ErrorMessage = "Ingrese el código enviado.")]
[Display(Name = "Código de inicio de sesión")]
public string OtpCode { get; set; }
}
public IActionResult OnGet(string loginType, string documentNumber)
{
if (User.Identity.IsAuthenticated)
{
return RedirectToPage("~/LoginWithOtp");
}
else
{
LoginType = loginType;
List<SATCloudUser> _users = new List<SATCloudUser>();
_users = _userManager.Users.Where(x => x.DocumentNumber == documentNumber).ToList();
SATCloudUser _satUser = _users[0];
TempData["Username"] = _satUser.Email;
TempData["PhoneNumber"] = _satUser.PhoneNumber;
return Page();
}
}
public async Task<IActionResult> OnPostAsync(string returnUrl = null)
{
List<SATCloudUser> _users = new List<SATCloudUser>();
_users = _userManager.Users.Where(x => x.DocumentNumber == DocumentNumber).ToList();
SATCloudUser _satUser = _users[0];
if (ModelState.IsValid)
{
var result = await _userManager.VerifyTwoFactorTokenAsync(_satUser, "Email", Input.OtpCode);
if (result)
{
returnUrl = returnUrl ?? Url.Content("~/Home/Index");
var auth = await HttpContext.AuthenticateAsync(IdentityConstants.ApplicationScheme);
var authenticationMethod = auth?.Principal?.FindFirstValue(ClaimTypes.AuthenticationMethod);
await _signInManager.SignInAsync(_satUser, false, authenticationMethod);
return LocalRedirect(returnUrl);
}
else
{
TempData["Username"] = _satUser.Email;
TempData["PhoneNumber"] = _satUser.PhoneNumber;
TempData["messageEnterOtp"] = "InvalidToken";
return Page();
}
}
else
{
return Page();
}
}
public async void OnPostResendAsync()
{
List<SATCloudUser> _users = new List<SATCloudUser>();
_users = _userManager.Users.Where(x => x.DocumentNumber == DocumentNumber).ToList();
SATCloudUser _satUser = _users[0];
var token = await _userManager.GenerateTwoFactorTokenAsync(_satUser, "Email");
if(LoginType == "sms")
{
AlertsManager _alertManager = new AlertsManager();
string phoneNumber = "+57" + _satUser.PhoneNumber;
string message = $"Código de inicio de sesión en Better Together SE: {token}. Por favor no comparta este código.";
await _alertManager.SendTextMessageAsync(phoneNumber, message);
}
else if(LoginType == "email")
{
EmailManager _emailManager = new EmailManager();
await _emailManager.NewTokenEmail(_satUser.Email, token);
}
}
}
}
A new instance of the EnterOtpModel class is created for each request. So the state of its properties is not preserved between different requests. You can add hidden input elements inside the resend form so that LoginType and DocumentNumber are re-sent again to the EnterOtpModel.
<form asp-page-handler="resend" method="post">
<input type="hidden" asp-for="LoginType" />
<input type="hidden" asp-for="DocumentNumber" />
<button id="resendToken" type="submit" class="btn btn-dark">Reenviar código</button>
</form>

ASP.NET Core localize .cs file in Razor Pages

There is a project on ASP.NET 5.0 with Identity.
Need help in how to translate messages in .cs files Razor Page.
Startup.cs looks like that
namespace localizeTest
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddLocalization(opt => { opt.ResourcesPath = "Resources"; });
services.AddMvc().AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix).AddDataAnnotationsLocalization();
services.Configure<RequestLocalizationOptions>(
opt =>
{
var suppoortedCulteres = new List<CultureInfo>
{
new CultureInfo("ru"),
new CultureInfo("en")
};
opt.DefaultRequestCulture = new RequestCulture("ru");
opt.SupportedCultures = suppoortedCulteres;
opt.SupportedUICultures = suppoortedCulteres;
}
);
services.AddDNTCaptcha(options =>
{
options.UseCookieStorageProvider();
});
string connection = Configuration["ConnectionStrings:DefaultConnection"];
ServerVersion vesrion = ServerVersion.AutoDetect(connection);
services.AddDbContext<ApplicationDbContext>(options =>
options.UseMySql(connection, vesrion));
services.AddDatabaseDeveloperPageExceptionFilter();
services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
.AddEntityFrameworkStores<ApplicationDbContext>();
services.AddControllersWithViews();
services.AddRazorPages();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseMigrationsEndPoint();
}
else
{
app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseRequestLocalization(app.ApplicationServices.GetRequiredService<IOptions<RequestLocalizationOptions>>().Value);
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
}
}
}
In the Resources folder created two files:
/Areas/Identity/Pages/Account/Login.en.resx
/Areas/Identity/Pages/Account/Login.ru.resx
Sample page
Areas/Identity/Pages/Account/Login.cshtml
#page
#model LoginModel
#inject Microsoft.AspNetCore.Mvc.Localization.IViewLocalizer localizer
#{
ViewData["Title"] = localizer["Login"];
}
<div class="container">
<div class="row h-100">
<div class="col-12 col-md-10 mx-auto my-auto">
<div class="card auth-card">
<div class="card-body">
<h1 class="mb-4">#ViewData["Title"]</h1>
<h4 class="pb-2">#localizer["Welcome"]</h4>
<form id="account" method="post">
<div asp-validation-summary="All" class="text-danger"></div>
<div class="form-group">
<label asp-for="Input.Email">#localizer["Email"]</label>
<input asp-for="Input.Email" class="form-control" placeholder="#localizer["YourEmail"]" required="">
<span asp-validation-for="Input.Email" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Input.Password">#localizer["Password"]</label>
<input asp-for="Input.Password" class="form-control" placeholder="#localizer["YourPassword"]" required="">
<span asp-validation-for="Input.Password" class="text-danger"></span>
</div>
<div class="form-group">
<div class="custom-control custom-checkbox">
<input class="custom-control-input" asp-for="Input.RememberMe">
<label class="custom-control-label" asp-for="Input.RememberMe">#localizer["RememberMe"]</label>
</div>
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary">#localizer["SignIn"]</button>
</div>
<div class="form-group">
<p>
<a id="forgot-password" asp-page="./ForgotPassword">#localizer["ForgotPass"]</a>
</p>
<p>
<a asp-page="./Register" asp-route-returnUrl="#Model.ReturnUrl">#localizer["ЗарегестрироватьсяКакНовый"]</a>
</p>
<p>
<a id="resend-confirmation" asp-page="./ResendEmailConfirmation">#localizer["EmailConf"]</a>
</p>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
#section Scripts {
<partial name="_ValidationScriptsPartial" />
}
Good, localize in Page View work it!
But, localize in Page Model not work.
File Areas/Identity/Pages/Account/Login.cshtml.cs
namespace localizeTest.Areas.Identity.Pages.Account
{
[AllowAnonymous]
public class LoginModel : PageModel
{
private readonly UserManager<IdentityUser> _userManager;
private readonly SignInManager<IdentityUser> _signInManager;
private readonly ILogger<LoginModel> _logger;
private readonly IStringLocalizer<LoginModel> _stringLocalizer;
public LoginModel(SignInManager<IdentityUser> signInManager,
ILogger<LoginModel> logger,
UserManager<IdentityUser> userManager,
IStringLocalizer<LoginModel> stringLocalizer)
{
_userManager = userManager;
_signInManager = signInManager;
_logger = logger;
_stringLocalizer = stringLocalizer;
}
[BindProperty]
public InputModel Input { get; set; }
public IList<AuthenticationScheme> ExternalLogins { get; set; }
public string ReturnUrl { get; set; }
[TempData]
public string ErrorMessage { get; set; }
public class InputModel
{
[Display(Name = "Email")]
[Required(ErrorMessage = "{0} is required")]
[EmailAddress]
public string Email { get; set; }
[Display(Name = "Password")]
[Required(ErrorMessage = "{0} is required")]
[DataType(DataType.Password)]
public string Password { get; set; }
[Display(Name = "RememberMe")]
public bool RememberMe { get; set; }
}
public async Task OnGetAsync(string returnUrl = null)
{
if (!string.IsNullOrEmpty(ErrorMessage))
{
ModelState.AddModelError(string.Empty, ErrorMessage);
}
returnUrl ??= Url.Content("~/Books/List");
// Clear the existing external cookie to ensure a clean login process
await HttpContext.SignOutAsync(IdentityConstants.ExternalScheme);
ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList();
ReturnUrl = returnUrl;
}
public async Task<IActionResult> OnPostAsync(string returnUrl = null)
{
returnUrl ??= Url.Content("~/Books/List");
string WrongLoggin = _stringLocalizer["НеВерныйЛогин"].Value;
ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList();
if (ModelState.IsValid)
{
// This doesn't count login failures towards account lockout
// To enable password failures to trigger account lockout, set lockoutOnFailure: true
var result = await _signInManager.PasswordSignInAsync(Input.Email, Input.Password, Input.RememberMe, lockoutOnFailure: false);
if (result.Succeeded)
{
_logger.LogInformation("User logged in.");
return LocalRedirect(returnUrl);
}
if (result.RequiresTwoFactor)
{
return RedirectToPage("./LoginWith2fa", new { ReturnUrl = returnUrl, RememberMe = Input.RememberMe });
}
if (result.IsLockedOut)
{
_logger.LogWarning("User account locked out.");
return RedirectToPage("./Lockout");
}
else
{
ModelState.AddModelError(string.Empty, WrongLoggin);
return Page();
}
}
// If we got this far, something failed, redisplay form
return Page();
}
}
}
How to translate text in .cs files, how to make it work?
[Display(Name = "How Translate With Text?")]
[Required(ErrorMessage = "How {0} Translate with Text?")]
Img Login Ru
Img Login En
I tried examples as for pages of controllers.
Created resources with the name LoginModel+InnerModel.en.resx and LoginModel+InnerModel.ru.resx.
But it did't give results.
P.S. Sorry for Google translate, but i need help.
P.S.2. Localization made on the example of this video
First you need to add AddDataAnnotationsLocalization in your Stratup,
services.AddLocalization(options => options.ResourcesPath = "Resources");
services.AddRazorPages().AddDataAnnotationsLocalization();
Then you need to name your resource file like
Areas.Identity.Pages.Account.LoginModel+InputModel.en-US.resx
For any nested model in LoginModel, you need to use + instead of .
For the details you can see the doc:
DataAnnotations localization.

I wanted to perform crud operations for Admin Panel of an ecommerce project but not able to edit image gallery in asp.net core

ProductModel class file
public class ProductModel
{
public int ProductID { get; set; }
public string ProductName { get; set; }
public string ProductDesc { get; set; }
public string Image { get; set; }
public IFormFile Img { get; set; }
public IFormFileCollection GalleryImages { get; set; }
public List<ProductGalleryModel> ProductGallery { get;set;}
}
ProductGalleryModel class file
public class ProductGalleryModel
{
public int ID { get; set; }
public int ProductId { get; set; }
public string Name { get; set; }
public string URL { get; set; }
public IFormFileCollection GalleryImages { get; set; }
public List<ProductGalleryModel> ProductGallery { get; set; }
}
ProductController class file
public class ProductController : Controller
{
private readonly IProductRepository _productRepository = null;
public ProductController(IProductRepository productRepository)
{
_productRepository = productRepository;
}
public async Task<IActionResult> AddNewProduct(bool isSuccess = false, int prodId = 0)
{
ViewBag.Categories = new SelectList(await _categoryRepository.GetAllCategories(), "CatID", "CategoryName");
ViewBag.IsSuccess = isSuccess;
ViewBag.ProductID = prodId;
return View();
}
[HttpPost]
public async Task<IActionResult> AddNewProduct(ProductModel productModel)
{
if (ModelState.IsValid)
{
if (productModel.Img1 != null)
{
string folder = "images/product/cover/";
productModel.Image1 = await UploadImage(folder, productModel.Img1);
}
if (productModel.GalleryImages != null)
{
string folder = "images/product/cover/gallery/";
productModel.ProductGallery = new List<ProductGalleryModel>();
foreach (var file in productModel.GalleryImages)
{
var gallery = new ProductGalleryModel()
{
Name = file.FileName,
URL = await UploadImage(folder, file)
};
productModel.ProductGallery.Add(gallery);
}
}
var id = await _productRepository.AddProduct(productModel);
if (id > 0)
{
return RedirectToAction(nameof(AddNewProduct), new { isSuccess = true, prodId = id });
}
}
ViewBag.Categories = new SelectList(await _categoryRepository.GetAllCategories(), "CatID", "CategoryName");
return View();
}
private async Task<string> UploadImage(string folderPath, IFormFile file)
{
folderPath += Guid.NewGuid().ToString() + "_" + file.FileName;
string serverfolderpath = Path.Combine(_webHostEnvironment.WebRootPath, folderPath);
await file.CopyToAsync(new FileStream(serverfolderpath, FileMode.Create));
return "/" + folderPath;
}
public async Task<IActionResult> GetProductGallery(int id)
{
var data = await _productRepository.GetProductById(id);
return View(data);
}
public async Task<IActionResult> EditProductGallery (int id, bool isSuccess = false)
{
ViewBag.IsSuccess = isSuccess;
ViewBag.ProductID = id;
var ListOfProducts = await _productRepository.GetProductById(id);
ViewData["ProductGallery"] = ListOfProducts.ProductGallery;
return View(ListOfProducts);
}
public async Task<PartialViewResult> RenderProduct(int id)
{
var ListOfProducts = await _productRepository.GetProductById(id);
ViewData["ProductGallery"] = ListOfProducts.ProductGallery;
return PartialView(ListOfProducts);
}
public async Task<PartialViewResult> RenderProductGallery(int id)
{
var ListOfProducts = await _productRepository.getProductGallery(id);
ViewData["ProductId"] = ListOfProducts.ProductGallery;
return PartialView(ListOfProducts);
}
[HttpPost]
public async Task<IActionResult> EditProductGallery(ProductGalleryModel productGalleryModel)
{
if (ModelState.IsValid)
{
if (productGalleryModel.URL != null)
{
if (productGalleryModel.GalleryImages != null)
{
string fileName = Path.GetFileName(productGalleryModel.GalleryImages.ToString());
string filePath = Path.Combine(_webHostEnvironment.WebRootPath, fileName);
System.IO.File.Delete(filePath);
string folder = "images/product/cover/gallery/";
productGalleryModel.ProductGallery = new List<ProductGalleryModel>();
foreach (var file in productGalleryModel.GalleryImages)
{
var gallery = new ProductGalleryModel()
{
Name = file.FileName,
URL = await UploadImage(folder, file)
};
productGalleryModel.ProductGallery.Add(gallery);
}
await _productRepository.UpdateProductGallery(productGalleryModel.ID, productGalleryModel);
}
}
return RedirectToAction("GetAllProducts", new { isSuccess = true, ViewBag.ProductID });
}
return View();
}
}
}
ProductRepository for all get and edit methods
public class ProductRepository : IProductRepository
{
public async Task<ProductGalleryModel> getProductGallery(int id)
{
var result = await _prcContext.tblProductGalleries.Where(x => x.ProductsProductID == id).
Select(getgallerybyid => new ProductGalleryModel()
{
URL = getgallerybyid.URL,
}).FirstOrDefaultAsync();
return result;
}
public async Task<ProductModel> GetProductById(int id)
{
return await _prcContext.tblProducts.Where(x => x.ProductID == id).
Select(getproductbyId => new ProductModel()
{
ProductID = getproductbyId.ProductID,
ProductName = getproductbyId.ProductName,
ProductDesc = getproductbyId.ProductDesc,
Image1 = getproductbyId.Image1,
Image2 = getproductbyId.Image2,
Image3 = getproductbyId.Image3,
Image4 = getproductbyId.Image4,
OldPrice = getproductbyId.OldPrice,
NewPrice = getproductbyId.NewPrice,
Discount = getproductbyId.Discount,
CategoryId = getproductbyId.CategoryId,
ProductGallery = getproductbyId.productGallery.Select(g => new ProductGalleryModel()
{
ID = g.GalleryID,
ProductId = g.ProductsProductID,
Name = g.Name,
URL= g.URL
}).ToList()
}).FirstOrDefaultAsync();
}
public async Task<ProductModel> UpdateProduct(int id, ProductModel productModel)
{
var updateProduct = await _prcContext.tblProducts.FirstOrDefaultAsync(x => x.ProductID == id);
if (updateProduct != null)
{
updateProduct.ProductName = productModel.ProductName;
updateProduct.ProductDesc = productModel.ProductDesc;
updateProduct.Image1 = productModel.Image1;
updateProduct.Image2 = productModel.Image2;
updateProduct.Image3 = productModel.Image3;
updateProduct.Image4 = productModel.Image4;
updateProduct.OldPrice = productModel.OldPrice;
updateProduct.NewPrice = productModel.NewPrice;
updateProduct.Discount = productModel.Discount;
updateProduct.CategoryId = productModel.CategoryId;
}
await _prcContext.SaveChangesAsync();
return productModel;
}
public async Task<ProductGalleryModel> UpdateProductGallery(int id, ProductGalleryModel productGalleryModel)
{
var updateProductGallery = await _prcContext.tblProductGalleries.FirstOrDefaultAsync(x => x.ProductsProductID == id);
if (updateProductGallery != null)
{
var newproduct = new List<tblProductGallery>();
foreach (var gallery in newproduct)
{
updateProductGallery.URL = productGalleryModel.URL;
}
await _prcContext.SaveChangesAsync();
}
return productGalleryModel;
}
}
Edit Product Gallery View file
#model ProductGalleryModel
#{
ViewData["Title"] = "Edit Product Gallery";
Layout = "~/Areas/Admin/Views/Shared/_AdminLayout.cshtml";
}
<style>
.img-fluid {
width: 250px;
height: 250px;
}
</style>
<div class="">
<!-- Content Header (Page header) -->
<section class="content-header">
<div class="container-fluid">
<div class="row mb-2">
<div class="col-md-6">
<h1>Edit Product Gallery</h1>
</div>
<div class="col-md-6">
<ol class="breadcrumb float-md-right">
<li class="breadcrumb-item"><a asp-action="Index" asp-controller="Home">Home</a></li>
<li class="breadcrumb-item"><a asp-action="GetAllProducts" asp-controller="Product">Products</a></li>
<li class="breadcrumb-item active">Edit Product Gallery</li>
</ol>
</div>
</div>
</div><!-- /.container-fluid -->
</section>
<section class="content">
<div class="container-fluid">
<div class="card card-primary py-2">
<div class="card-header">
<h3 class="card-title">Existing Gallery</h3>
</div>
<div class="card-body">
<div class="row">
<input type="hidden" value="#ViewData["ProductGallery"]" />
<partial name="~/Areas/Admin/Views/RenderProduct.cshtml"
view-data="ViewData" />
</div>
</div>
</div>
<div class="card card-primary">
<div class="card-header">
<h3 class="card-title">Update Gallery</h3>
</div>
<form method="post" enctype="multipart/form-data" asp-action="EditProductGallery" asp-controller="Product">
<div class="card-body">
<div class="row">
<partial name="~/Areas/Admin/Views/RenderProductGallery.cshtml" view-data="ViewData" />
<div class="">
</div>
</div>
<div class="card-footer">
<input type="submit" value="Update" class="btn btn-success" />
</div>
</form>
</div>
</div>
</section>
</div>
#section Scripts
{
<script>
$(document).ready(function () {
$('.custom-file-input').on("change", function () {
var filename = $(this).val().split("\\").pop();
$(this).next('.custom-file-label').html(filename);
});
});
</script>
}
Product PartialView
#model ProductModel
<div class="col-sm-3">
<img src="#Model.Image1" class="img-fluid mb-2" alt="white sample" />
</div>
#for (int i = 0; i < Model.ProductGallery.Count(); i++)
{
<div class="col-sm-3">
<img src="#Model.ProductGallery[i].URL" class="img-fluid mb-2" alt="white sample" />
</div>
}
Product Gallery PartialView
model ProductGalleryModel
#{
ViewData["ProductGallery"] = true;
}
<div class="">
<input type="hidden" value="#Model.ProductId" />
#*<input type="hidden" value="#Model.ProductGallery" />*#
</div>
<div class="col-md-6">
<div class="form-group">
<label asp-for="GalleryImages"></label>
<div class="custom-file">
<input asp-for="GalleryImages" class="custom-file-input" id="inputGroupFile01">
<label class="custom-file-label" for="inputGroupFile01">Choose file</label>
</div>
<span asp-validation-for="GalleryImages" class="text-danger"></span>
</div>
</div>
#section Scripts
{
<script>
$(document).ready(function () {
$('.custom-file-input').on("change", function () {
var filename = $(this).val().split("\\").pop();
$(this).next('.custom-file-label').html(filename);
});
});
</script>
}
I am able to return the ProductPartialView with desired results but when i am calling the ProductGalleryPartialView then i am getting an Exception: The model item passed into the ViewDataDictionary is of type 'PRC_webapp.Areas.Admin.Models.ProductModel', but this ViewDataDictionary instance requires a model item of type 'PRC_webapp.Areas.Admin.Models.ProductGalleryModel'.
public IActionResult Index()
{
return View(_context.students);
}
public IActionResult Create()
{
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create(student student)
{
if (!ModelState.IsValid)
{
return View();
}
student.Image = await student.Photo.SaveFileAsync(_env.WebRootPath, "images");
await _context.students.AddAsync(student);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
public async Task<IActionResult> Update(int? id)
{
if (id == null)
{
return BadRequest();
}
var student = await _context.students.FindAsync(id);
if (student == null)
{
return NotFound();
}
return View(student);
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Update(int? id, student newstudent)
{
if (id == null)
{
return BadRequest();
}
var oldstudent = _context.students.Find(id);
if (oldstudent == null)
{
return NotFound();
}
if (!ModelState.IsValid)
{
return View();
}
var path = Helper.GetPath(_env.WebRootPath, "img", oldstudent.Image);
if (System.IO.File.Exists(path))
{
System.IO.File.Delete(path);
}
newstudent.Image = await newstudent.Photo.SaveFileAsync(_environment.WebRootPath, "images");
oldstudent.Image = newstudent.Image;
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
public async Task<IActionResult> Delete(int id)
{
if (id == null)
{
return BadRequest();
}
var student = _context.students.Find(id);
if (student == null)
{
return NotFound();
}
var path = Helper.GetPath(_environment.WebRootPath, "img", student.Image);
if (System.IO.File.Exists(path))
{
System.IO.File.Delete(path);
}
_context.students.Remove(student);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}

MVC checkbox list bounding to model

I am trying to collect all the options that the user have selected for a checkbox list. The checkbox list is built using a foreach loop and I have a int[] that I am trying to put the id into. Any help would be great.
View
#{
int idxFormats = 0;
foreach (var item in Model.ListOfFormats)
{
<div class='col-md-6'>
<input type="checkbox" value=#item.Value name="chkFormat" />
<label asp-for=#item.Selected>#Html.Raw(#item.Name)</label>
#Html.HiddenFor(m => Model.selectedFormats[idxFormats]);
</div>
idxFormats++;
}
#Html.ValidationMessageFor(model => model.selectedFormats[idxFormats])
}
Model
public List<GenericValues> ListOfFormats { get; set; }
[Display(Name = "At least one 'Format' must be selected")]
public int[] selectedFormats { get; set; }
Change the Checkbox name to selectedFormats
<input type="checkbox" value=#item.Value name="selectedFormats" />
Test example:
Model:
public class Test
{
public List<GenericValues> ListOfFormats { get; set; }
public int[] selectedFormats { get; set; }
}
public class GenericValues
{
public int Value { get; set; }
public string Name { get; set; }
public bool Selected { get; set; }
}
View:
#model Test
#{
ViewData["Title"] = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h1>Index</h1>
<form method="post">
#{
foreach (var item in Model.ListOfFormats)
{
<div class='col-md-6'>
<input type="checkbox" value=#item.Value name="selectedFormats" />
<label asp-for=#item.Selected>#Html.Raw(#item.Name)</label>
</div>
}
}
<input type="submit" value="submit" />
</form>
Controller:
public IActionResult Index()
{
Test test = new Test
{
ListOfFormats = new List<GenericValues>
{
new GenericValues
{
Name = "A",
Value = 1,
},
new GenericValues
{
Name = "B",
Value = 2,
},
new GenericValues
{
Name = "C",
Value = 3,
}
}
};
return View(test);
}
[HttpPost]
public IActionResult Index(Test test)
{
return Ok();
}
Result:
if you are looking to put id as value of your idxFormats then use this code in your checkbox:
<input type="checkbox" value=#item.Value name="chkFormat" id="#idxFormats" />
Edit:
I am not so familiar with c#, I tested with minimum code :
// Replace the model correct path by yours
#model IEnumerable<WebApplication1.Models.MyModels.ListOfFormats>
#{
int idxFormats = 0;
foreach (var item in Model)
{
<div class='col-md-6'>
<input type="checkbox" value=#item.Value name="chkFormat" id="#idxFormats"/>
<label>#Html.Raw(#item.Name)</label>
</div>
idxFormats++;
}
}

LINQ Query return null value

when i use Linq query to fetching or compare data within DB it return me null value in morning it works right but now it not working it through exception.
model
public partial class CandidateRegistration
{
public int CandidateID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Email { get; set; }
public string Password { get; set; }
public bool RegisterAs { get; set; }
public Nullable<bool> ApprovedBit { get; set; }
}
public virtual DbSet<CandidateRegistration> CandidateRegistrations { get; set; }
Controller
public ActionResult Login(string emaillogin, string passwordslogin, bool registerAs, string Rememberme)
{
bool aprovedbitforemployer = false;
if (registerAs == true)
{
var checkApprovedBitForEmployer = DB.EmployerRegistrations.FirstOrDefault(e => e.Email == obj.Email);
aprovedbitforemployer = Convert.ToBoolean((checkApprovedBitForEmployer.ApprovedBit));
if (aprovedbitforemployer != false)
{
if(checkApprovedBitForEmployer.Email == emaillogin && checkApprovedBitForEmployer.Passwords == passwordslogin)
{
Session["Username"] = checkApprovedBitForEmployer.Email.ToString();
Session["Passwords"] = checkApprovedBitForEmployer.Passwords.ToString();
Session["Employee"] = "Employer";
}
}
else
{
TempData["Notpermission"] = "Your account is in activation process please wait...";
}
}
else if (registerAs == false)
{
CandidateRegistration checkApprovedBitForEmplloyee = DB.CandidateRegistrations.FirstOrDefault(c => c.Email == emaillogin);
aprovedbitforemployer = Convert.ToBoolean((checkApprovedBitForEmplloyee.ApprovedBit));
if(aprovedbitforemployer == true)
{
if (checkApprovedBitForEmplloyee.Email == emaillogin && checkApprovedBitForEmplloyee.Password == passwordslogin)
{
Session["Username"] = checkApprovedBitForEmplloyee.Email.ToString();
Session["Passwords"] = checkApprovedBitForEmplloyee.Password.ToString();
Session["Employee"] = "Employee";
}
}
else
{
TempData["Notpermission"] = "Your account is in activation process please wait...";
}
}
else
{
TempData["Emailorpasswordmistakes"] = "Email or password incorrect";
}
return View();
}
"checkApprovedBitForEmployer" return null value it=n this variable.
View
#using (Html.BeginForm("Login", "Home", FormMethod.Post))
{
<div class="col-md-6 account">
<h3>Login</h3>
<span id="Emessage" onshow="show();"> #TempData["Notpermission"] </span>
<label for="">Username or email address *</label>
<div class="form-group">
<input type="email" name="emaillogin" id="emaillogin" class="form-control input-sm " placeholder="Email Address" style="width:70%; height: 35px; text-transform:none;">
</div>
<label for="">Password *</label>
<div class="form-group">
<input type="password" name="passwordslogin" id="passwordslogin" class="form-control input-sm" placeholder="Password" style="width:70%; height: 35px; text-transform:none; ">
<span id="Emessage" onshow="show();" >#TempData["Emailorpasswordmistakes"]</span>
</div>
<div class="form-group">
#Html.DropDownList("RegisterAs", new List<SelectListItem>()
{
new SelectListItem() { Text= "Register As", Selected = true },
new SelectListItem() { Text= "Employer", Value = "true" },
new SelectListItem() { Text= "Employee", Value = "false" }
}, new { htmlAttributes = new { #class = "form-control" } })
</div>
<button>Login</button>
<input type="checkbox" id="rememberme" name="Rememberme" value="forever"><span>Remember me</span>
<br />
Lost your Password
</div>
}
i am using html form and i want to use this but only tell me why it not fetch data from database.
var checkApprovedBitForEmployer = DB.EmployerRegistrations.FirstOrDefault(e => e.Email == obj.Email);
In above line you are checking email address from database with Obj.Email.i guess you need to compare with emaillogin.