Bundle IdentityUser to ticket - c#

This is a homework assignment. Where I have to make a website with MVC 2.2 and Make it possible to make a ticket with some basic info and link IdentityUser to the ticket.
The Class:
public class Ticket
{
public int ID { get; set; }
[Required]
public string Klant { get; set; }
[Required]
public string Applicatie { get; set; }
[Required]
public string Onderwerp { get; set; }
[Required]
public string Omschrijving { get; set; }
public DateTime Datum { get; set; }
public string Status { get; set; }
}
The Controller:
public class TicketsController : Controller
{
private readonly ApplicationDbContext _context;
UserManager<IdentityUser> _userManager;
public TicketsController(UserManager<IdentityUser> userManager)
{
_userManager = userManager;
}
public TicketsController(ApplicationDbContext context)
{
_context = context;
}
// GET: Tickets
public async Task<IActionResult> Index()
{
return View(await _context.Ticket.ToListAsync());
}
This is added to the controller at the moment.
UserManager<IdentityUser> _userManager;
public TicketsController(UserManager<IdentityUser> userManager)
{
_userManager = userManager;
}
So I was asking myself how to do this and I would really appreciate it if someone knows what to do and can explain it well.
Thanks in advance.
If you need more info just ask.

Here is a working scenario for creating one ticket with one IdentityUser.
Ticket
public class Ticket
{
public int ID { get; set; }
[Required]
public string Klant { get; set; }
[Required]
public string Applicatie { get; set; }
[Required]
public string Onderwerp { get; set; }
[Required]
public string Omschrijving { get; set; }
public DateTime Datum { get; set; }
public string Status { get; set; }
public string IdentityUserId { get; set; }
public virtual IdentityUser IdentityUser { get; set; }
}
ApplicationDbContext
public class ApplicationDbContext : IdentityDbContext
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
}
public DbSet<Ticket> Tickets { get; set; }
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
builder.Entity<Ticket>().HasOne(t => t.IdentityUser).WithMany();
}
}
TicketsController
public class TicketsController : Controller
{
private readonly ApplicationDbContext _context;
private readonly UserManager<IdentityUser> _userManager;
public TicketsController(ApplicationDbContext context
, UserManager<IdentityUser> userManager)
{
_context = context;
_userManager = userManager;
}
// GET: Tickets
public async Task<IActionResult> Index()
{
var applicationDbContext = _context.Tickets.Include(t => t.IdentityUser);
return View(await applicationDbContext.ToListAsync());
}
// GET: Tickets/Details/5
public async Task<IActionResult> Details(int? id)
{
if (id == null)
{
return NotFound();
}
var ticket = await _context.Tickets
.Include(t => t.IdentityUser)
.FirstOrDefaultAsync(m => m.ID == id);
if (ticket == null)
{
return NotFound();
}
return View(ticket);
}
// GET: Tickets/Create
public IActionResult Create()
{
ViewData["IdentityUserId"] = new SelectList(_context.Users, "Id", "Id");
return View();
}
// POST: Tickets/Create
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("ID,Klant,Applicatie,Onderwerp,Omschrijving,Datum,Status,IdentityUserId")] Ticket ticket)
{
if (ModelState.IsValid)
{
_context.Add(ticket);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
ViewData["IdentityUserId"] = new SelectList(_context.Users, "Id", "Id", ticket.IdentityUserId);
return View(ticket);
}
// GET: Tickets/Edit/5
public async Task<IActionResult> Edit(int? id)
{
if (id == null)
{
return NotFound();
}
var ticket = await _context.Tickets.FindAsync(id);
if (ticket == null)
{
return NotFound();
}
ViewData["IdentityUserId"] = new SelectList(_context.Users, "Id", "Id", ticket.IdentityUserId);
return View(ticket);
}
// POST: Tickets/Edit/5
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(int id, [Bind("ID,Klant,Applicatie,Onderwerp,Omschrijving,Datum,Status,IdentityUserId")] Ticket ticket)
{
if (id != ticket.ID)
{
return NotFound();
}
if (ModelState.IsValid)
{
try
{
_context.Update(ticket);
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!TicketExists(ticket.ID))
{
return NotFound();
}
else
{
throw;
}
}
return RedirectToAction(nameof(Index));
}
ViewData["IdentityUserId"] = new SelectList(_context.Users, "Id", "Id", ticket.IdentityUserId);
return View(ticket);
}
// GET: Tickets/Delete/5
public async Task<IActionResult> Delete(int? id)
{
if (id == null)
{
return NotFound();
}
var ticket = await _context.Tickets
.Include(t => t.IdentityUser)
.FirstOrDefaultAsync(m => m.ID == id);
if (ticket == null)
{
return NotFound();
}
return View(ticket);
}
// POST: Tickets/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteConfirmed(int id)
{
var ticket = await _context.Tickets.FindAsync(id);
_context.Tickets.Remove(ticket);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
private bool TicketExists(int id)
{
return _context.Tickets.Any(e => e.ID == id);
}
}
Create.cshtml
#model CoreIdentity2.Models.Ticket
#{
ViewData["Title"] = "Create";
}
<h1>Create</h1>
<h4>Ticket</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="Klant" class="control-label"></label>
<input asp-for="Klant" class="form-control" />
<span asp-validation-for="Klant" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Applicatie" class="control-label"></label>
<input asp-for="Applicatie" class="form-control" />
<span asp-validation-for="Applicatie" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Onderwerp" class="control-label"></label>
<input asp-for="Onderwerp" class="form-control" />
<span asp-validation-for="Onderwerp" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Omschrijving" class="control-label"></label>
<input asp-for="Omschrijving" class="form-control" />
<span asp-validation-for="Omschrijving" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Datum" class="control-label"></label>
<input asp-for="Datum" class="form-control" />
<span asp-validation-for="Datum" 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">
<label asp-for="IdentityUserId" class="control-label"></label>
<select asp-for="IdentityUserId" class ="form-control" asp-items="ViewBag.IdentityUserId"></select>
</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");}
}

Related

ASP.net mvc create a new data does not work

when i try to create a new data from the form and i do not get any error and the page just refresh , without creating any new data . im using sql server and i have a ForeignKey from another table.
my course controller:
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Rendering; using Microsoft.EntityFrameworkCore; using SchoolGrades.Models;
namespace SchoolGrades.Controllers { public class CoursesController : Controller { private readonly UniDBContext _context;
public CoursesController(UniDBContext context)
{
_context = context;
}
// GET: Courses
public async Task<IActionResult> Index()
{
var uniDBContext = _context.Courses.Include(c => c.ProfessorsAfmNavigation);
return View(await uniDBContext.ToListAsync());
}
// GET: Courses/Details/5
public async Task<IActionResult> Details(string id)
{
if (id == null || _context.Courses == null)
{
return NotFound();
}
var course = await _context.Courses
.Include(c => c.ProfessorsAfmNavigation)
.FirstOrDefaultAsync(m => m.IdCourse == id);
if (course == null)
{
return NotFound();
}
return View(course);
}
// GET: Courses/Create
public IActionResult Create()
{
ViewData["ProfessorsAfm"] = new SelectList(_context.Professors, "Afm", "Afm");
return View();
}
// POST: Courses/Create
// To protect from overposting attacks, enable the specific properties you want to bind to.
// For more details, see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("IdCourse,CourseTitle,CourseSemester,ProfessorsAfm")] Course course)
{
if (ModelState.IsValid)
{
_context.Add(course);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
ViewData["ProfessorsAfm"] = new SelectList(_context.Professors, "Afm", "Afm", course.ProfessorsAfm);
return View(course);
}
// GET: Courses/Edit/5
public async Task<IActionResult> Edit(string id)
{
if (id == null || _context.Courses == null)
{
return NotFound();
}
var course = await _context.Courses.FindAsync(id);
if (course == null)
{
return NotFound();
}
ViewData["ProfessorsAfm"] = new SelectList(_context.Professors, "Afm", "Afm", course.ProfessorsAfm);
return View(course);
}
// POST: Courses/Edit/5
// To protect from overposting attacks, enable the specific properties you want to bind to.
// For more details, see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(string id, [Bind("IdCourse,CourseTitle,CourseSemester,ProfessorsAfm")] Course course)
{
if (id != course.IdCourse)
{
return NotFound();
}
if (ModelState.IsValid)
{
try
{
_context.Update(course);
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!CourseExists(course.IdCourse))
{
return NotFound();
}
else
{
throw;
}
}
return RedirectToAction(nameof(Index));
}
ViewData["ProfessorsAfm"] = new SelectList(_context.Professors, "Afm", "Afm", course.ProfessorsAfm);
return View(course);
}
// GET: Courses/Delete/5
public async Task<IActionResult> Delete(string id)
{
if (id == null || _context.Courses == null)
{
return NotFound();
}
var course = await _context.Courses
.Include(c => c.ProfessorsAfmNavigation)
.FirstOrDefaultAsync(m => m.IdCourse == id);
if (course == null)
{
return NotFound();
}
return View(course);
}
// POST: Courses/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteConfirmed(string id)
{
if (_context.Courses == null)
{
return Problem("Entity set 'UniDBContext.Courses' is null.");
}
var course = await _context.Courses.FindAsync(id);
if (course != null)
{
_context.Courses.Remove(course);
}
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
private bool CourseExists(string id)
{
return (_context.Courses?.Any(e => e.IdCourse == id)).GetValueOrDefault();
}
}
}
`
my course model:
using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; using Microsoft.EntityFrameworkCore;
namespace SchoolGrades.Models;
[Table("course")] public partial class Course { [Key] [Column("idCOURSE")] [StringLength(25)] [Unicode(false)] public string IdCourse { get; set; } = null!;
[StringLength(60)]
[Unicode(false)]
public string CourseTitle { get; set; } = null!;
[StringLength(25)]
[Unicode(false)]
public string CourseSemester { get; set; } = null!;
[Column("PROFESSORS_AFM")]
[StringLength(25)]
[Unicode(false)]
public string ProfessorsAfm { get; set; } = null!;
[InverseProperty("CourseIdCourseNavigation")]
public virtual CourseHasStudent? CourseHasStudent { get; set; }
[ForeignKey("ProfessorsAfm")]
[InverseProperty("Courses")]
public virtual Professor ProfessorsAfmNavigation { get; set; } = null!;
}
and course create view :
#model SchoolGrades.Models.Course
#{
ViewData["Title"] = "Create";
}
<h1>Create</h1>
<h4>Course</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="IdCourse" class="control-label"></label>
<input asp-for="IdCourse" class="form-control" />
<span asp-validation-for="IdCourse" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="CourseTitle" class="control-label"></label>
<input asp-for="CourseTitle" class="form-control" />
<span asp-validation-for="CourseTitle" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="CourseSemester" class="control-label"></label>
<input asp-for="CourseSemester" class="form-control" />
<span asp-validation-for="CourseSemester" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="ProfessorsAfm" class="control-label"></label>
<select asp-for="ProfessorsAfm" class ="form-control" asp-items="ViewBag.ProfessorsAfm"></select>
</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");}
}
i removed the if statement from the course controller .
if (ModelState.IsValid)
{ _context.Add(course);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
and i kept it like this and it worked and i could create a new data in the table after i removed the if statement .
_context.Add(course);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
any other solutions please.

How to Get Selected List of DropDownList from Database or Model and Populate in Dropdown on View

I am performing a Bitwise-Create operation on my modal(view) and I am to select a dropdown list of users from another table/model and bind to the view so I can forward the request to them. I want to select users based on a certain role, if possible: but I just want to select the users from the database table.
If you need any other model or controller, kindly prompt me so i add it.
Please help..
Below is my Code:
Cshtml Code for the Modal View:(Removed Other TextFields):
So where I have the select tags, i want to get the select list of users and add it.
<div class="row">
<div class="col-md-12">
<form asp-action="AddOrEdit" asp-route-id="#Model.BitwiseId" autocomplete="false" enctype="multipart/form-data">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="col-md-6">
<div class="form-group">
<label asp-for="AccountName" class="control-label"></label>
<input asp-for="AccountName" class="form-control" />
<span asp-validation-for="AccountName" class="text-danger"></span>
</div>
</div>
<div class="form-group">
<label asp-for="File" class="control-label"></label>
<input type="file" name="userfile" class="form-control" accept=".xlsx"/>
<span asp-validation-for="File" class="text-danger"></span>
</div>
<div class="form-group">
<label for="cars">Select 1st Approver </label>
<select name="group_heads" id="group_heads" class="form-control">
<option value="">Select</option>
<option value="2">Bobby</option>
</select>
</div>
<hr />
<div class="d-grid gap-2">
<input type="submit" value="Save" class="btn btn-primary" />
</div>
</form>
</div>
Code: Controller for the Bitwise - Add Method:
namespace BOGBitwiseApp.Controllers
{
public class BitwiseController : Controller
{
private readonly ApplicationDbContext _context;
public BitwiseController(ApplicationDbContext context)
{
_context = context;
}
public async Task<IActionResult> Index()
{
return View(await _context.Bitwises.ToListAsync());
}
// GET: Transaction/AddOrEdit(Insert)
// GET: Transaction/AddOrEdit/5(Update)
[NoDirectAccess]
public async Task<IActionResult> AddOrEdit(int id = 0)
{
if (id == 0)
return View(new BitwiseModel());
else
{
var bitwiseModel = await _context.Bitwises.FindAsync(id);
if (bitwiseModel == null)
{
return NotFound();
}
return View(bitwiseModel);
}
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> AddOrEdit(int id, [Bind("BitwiseId,..., Amount")] BitwiseModel bitwiseModel, ...)
{
if (ModelState.IsValid)
{
//New
if (id == 0)
{
string filename = userfile.FileName;
...
await userfile.CopyToAsync(stream);
var data = _context.Users.ToListAsync();
bitwiseModel.Date = DateTime.Now;
_context.Add(bitwiseModel);
await _context.SaveChangesAsync();
}
//Update
else
{
try
{
_context.Update(bitwiseModel);
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!BitwiseModelExists(bitwiseModel.BitwiseId))
{ return NotFound(); }
else
{ throw; }
}
}
return Json(new { isValid = true, html = Helper.RenderRazorViewToString(this, "_ViewAll", _context.Bitwises.ToList()) });
}
return Json(new { isValid = false, html = Helper.RenderRazorViewToString(this, "AddOrEdit", bitwiseModel) });
}
Model Code for Bitwise (Add):
public class BitwiseModel
{
[Key]
public int BitwiseId { get; set; }
[Required]
[Column(TypeName = "nvarchar(100)")]
[DisplayName("Customer Name")]
public string AccountName { get; set; }
[NotMapped]
[DisplayName("Invoice File")]
public IFormFile? File { get; set; }
}
**Model for Users Table:**
public class ApplicationUser : IdentityUser
{
public string? FirstName { get; set; }
public string? LastName { get; set; }
public int UsernameChangeLimit { get; set; } = 2;
public byte[]? ProfilePicture { get; set; }
}

Custom Validation Attribute not working in .NET 6

I have a model where I am trying to implement conditional validation. My few properties will be required only if the value for those properties are true in some other collection. I found some code here Conditional validation in MVC.NET Core (RequiredIf) but I am not understanding why it is not working in my case.
Expected case is, the validation should fire for "FirstName" field as it has true value in the collection and should not fire for Last Name field as it has false value in the collection. Currently validation is not firing at all for FirstName.
Here is my code:
Person.cs
public class Person
{
public int Id { get; set; }
//This property should be required only when this property exist in below class RequiredFieldsData.PropertiesPair() collection and has value true
[RequiredIf("FirstName", true, ErrorMessage = "First Name is required")]
public string FirstName { get; set; }
[RequiredIf("LastName", true, ErrorMessage ="Last name is required")]
public string LastName { get; set; }
}
public static class RequiredFieldsData
{
public static Dictionary<string, bool> PropertiesPair()
{
return new Dictionary<string, bool>
{
{"FirstName", true},
{"LastName", false }
};
}
}
[AttributeUsage(AttributeTargets.Property)]
public class RequiredIfAttribute : ValidationAttribute, IClientModelValidator
{
private string PropertyName { get; set; }
private bool DesiredValue { get; set; }
public RequiredIfAttribute(string propertyName, bool desiredValue)
{
PropertyName = propertyName;
DesiredValue = desiredValue;
}
protected override ValidationResult IsValid(object value, ValidationContext context)
{
object instance = context.ObjectInstance;
Type type = instance.GetType();
bool propertyValue = RequiredFieldsData.PropertiesPair().Any(t => t.Key == type.GetProperty(PropertyName).Name && t.Value == DesiredValue);
if (propertyValue && string.IsNullOrWhiteSpace(value?.ToString()))
{
return new ValidationResult(ErrorMessage);
}
return ValidationResult.Success;
}
public void AddValidation(ClientModelValidationContext context)
{
MergeAttribute(context.Attributes, "data-val", "true");
var errorMessage = FormatErrorMessage(context.ModelMetadata.GetDisplayName());
MergeAttribute(context.Attributes, "data-val-requiredif", errorMessage);
}
private bool MergeAttribute(IDictionary<string, string> attributes, string key, string value)
{
if (attributes.ContainsKey(key))
{
return false;
}
attributes.Add(key, value);
return true;
}
}
PersonController.cs
public class PersonController : Controller
{
// GET: PersonController
public ActionResult Index()
{
List<Person> list = new List<Person>
{
new Person
{
Id=1,
FirstName ="Ashwani",
LastName ="Singh"
}
};
return View(list);
}
// GET: PersonController/Details/5
public ActionResult Details(int id)
{
return View();
}
// GET: PersonController/Create
public ActionResult Create()
{
return View();
}
// POST: PersonController/Create
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(Person personModel)
{
try
{
if(ModelState.IsValid)
return RedirectToAction(nameof(Index));
return null;
}
catch
{
return View();
}
}
// GET: PersonController/Edit/5
public ActionResult Edit(int id)
{
return View();
}
// POST: PersonController/Edit/5
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(int id, IFormCollection collection)
{
try
{
return RedirectToAction(nameof(Index));
}
catch
{
return View();
}
}
// GET: PersonController/Delete/5
public ActionResult Delete(int id)
{
return View();
}
// POST: PersonController/Delete/5
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Delete(int id, IFormCollection collection)
{
try
{
return RedirectToAction(nameof(Index));
}
catch
{
return View();
}
}
}
Create.cshtml
#model Test.Models.Person
#{
ViewData["Title"] = "Create";
}
<h1>Create</h1>
<h4>Person</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="Id" class="control-label"></label>
<input asp-for="Id" class="form-control" />
<span asp-validation-for="Id" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="FirstName" class="control-label"></label>
<input asp-for="FirstName" class="form-control" />
<span asp-validation-for="FirstName" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="LastName" class="control-label"></label>
<input asp-for="LastName" class="form-control" />
<span asp-validation-for="LastName" 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");}
}
My project is in .NET 6 MVC.
Can anybody tell me where I am going wrong. Thank You

Pass list item wih viewmodel in .net core

I'm new to this and this might be quite easy for some people.
I'm struggling to connect a particular field (dropdown list item) between a View and a Controller. What I'm pretending is to associate a category (from a list) to a product.
For this particular Controller, my system as a Model, a Service and a ViewModel.
For the product class I have the following code:
public class DryGoodsProduct
{
public int Id { get; set; }
public string ProductName { get; set; }
[Display(Name = "Category")]
[Required]
public DryGoodsCategory DryGoodsCategory { get; set; }
public int DryGoodsCategoryId { get; set; }
public DryGoodsProduct()
{ }
public DryGoodsProduct(int id, string productName, DryGoodsCategory category)
{
Id = id;
ProductName = productName;
DryGoodsCategory = category;
}
}
The category class is the following:
public class DryGoodsCategory
{
public int Id { get; set; }
public string CategoryName { get; set; }
public string Description { get; set; }
public virtual ICollection<DryGoodsProduct> DryGoodsProducts { get; set; }
public DryGoodsCategory()
{
}
public DryGoodsCategory(int id, string categoryName)
{
Id = id;
CategoryName = categoryName;
}
}
The product service class is the following:
public class DryGoodsProductService
{
private readonly DB _context;
public DryGoodsProductService(DB context)
{
_context = context;
}
public async Task<List<DryGoodsProduct>> FindAllAsync()
{
return await _context.DryGoodsProducts
.Include(obj => obj.DryGoodsCategory)
.ToListAsync();
}
public async Task InsertAsync(DryGoodsProduct drygoodsProduct)
{
_context.Add(drygoodsProduct);
await _context.SaveChangesAsync();
}
public async Task<DryGoodsProduct> FindByIdAsync(int id)
{
return await _context.DryGoodsProducts
.Include(obj => obj.DryGoodsCategory)
.FirstOrDefaultAsync(x => x.Id == id);
}
public async Task RemoveAsync(int id)
{
try
{
var obj = await _context.DryGoodsProducts.FindAsync(id);
_context.DryGoodsProducts.Remove(obj);
await _context.SaveChangesAsync();
}
catch (IntegrityException e)
{
throw new IntegrityException(e.Message);
}
}
public async Task UpdateAsync(DryGoodsProduct drygoodsProduct)
{
bool hasAny = await _context.DryGoodsProducts.AnyAsync(x => x.Id == drygoodsProduct.Id);
if (!hasAny)
{
throw new NotFoundException("ID não encontrado");
}
try
{
_context.Update(drygoodsProduct);
await _context.SaveChangesAsync();
}
catch (DbConcurrencyException ex)
{
throw new DbConcurrencyException(ex.Message);
}
}
}
and the view model class is:
public class DryGoodsProductViewModel
{
public DryGoodsProduct drygoodsProduct { get; set; }
public virtual ICollection<DryGoodsCategory> DryGoodsCategories { get; set; }
}
the controller is the following:
public async Task<IActionResult> Create()
{
var categories = await _categoryService.FindAllAsync();
var product = new DryGoodsProduct();
var viewmodel = new DryGoodsProductViewModel()
{
drygoodsProduct = product,
DryGoodsCategories = categories,
};
return View(viewmodel);
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create(DryGoodsProduct product)
{
if (ModelState.IsValid)
{
await _productService.InsertAsync(product);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
return View(product);
}
and the create view :
enter #model Library.ViewModels.Logistics.DryGoodsProductViewModel
#{
ViewData["Title"] = "Create";
Layout = "~/Areas/Logistics/Views/Shared/_LogisticsLayout.cshtml"; }
<h1>Create</h1>
<h4>Products</h4>
<hr />
<div class="row">
<div class="col-md-4">
<form asp-action="Create" enctype="multipart/form-data">
#Html.AntiForgeryToken()
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="drygoodsProduct.ProductName" class="control-label"></label>
<input asp-for="drygoodsProduct.ProductName" class="form-control" />
<span asp-validation-for="drygoodsProduct.ProductName" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="drygoodsProduct.DryGoodsCategoryId" class="control-label"></label>
<select asp-for="drygoodsProduct.DryGoodsCategoryId" asp-items="#(new SelectList(Model.DryGoodsCategories, "Id", "CategoryName"))" class="form-control"></select>
<span asp-validation-for="drygoodsProduct.DryGoodsCategoryId" 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");}
}
So...
The error says:
An unhandled exception occurred while processing the request.
InvalidOperationException: The model item passed into the
ViewDataDictionary is of type
'Library.Models.Logistics.DryGoods.DryGoodsProduct', but this
ViewDataDictionary instance requires a model item of type
'Library.ViewModels.Logistics.DryGoodsProductViewModel'.
I mean, I've done something quit similar with another controller and everything is ok.
I would appreciate some feedback on how to solve this.

unable to create HttpGet controller to find user detail using identity

I have created authentication controller and there i was able to create HttpPost for login and logout but not HttpGet. what i'm trying is Only authenticated user can hit and return basic information about currently logged in user at a minimum Username,Staffid(if any)
i have created three role that is admin manager and staff.
namespace Web.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class AuthenticationController : ControllerBase
{
private readonly UserManager<User> userManager;
private readonly SignInManager<User> signInManager;
public object DefaultAuthenticationTypes { get; private set; }
public AuthenticationController(UserManager<User> userManager, SignInManager<User> signInManager)
{
this.userManager = userManager;
this.signInManager = signInManager;
}
[HttpPost("login")]
public async Task<ActionResult<UserDto>> Login(LoginDto dto)
{
var user = await userManager.FindByNameAsync(dto.UserName);
if (user == null)
{
return BadRequest();
}
var password = await signInManager.CheckPasswordSignInAsync(user, dto.Password, true);
if (!password.Succeeded)
{
return BadRequest();
}
await signInManager.SignInAsync(user, false, "Password");
return Ok(new UserDto
{
UserName = user.UserName
});
}
[HttpGet]
[Authorize]
public async Task<string> GetUserProfile()
{
var userName = await userManager.FindByNameAsync(HttpContext.User.Identity.Name);
var userId = userName.Id;
var roleId = User.IsInRole("Staff");
if (!(roleId.ToString() == "Staff"))
{
return userName.ToString();
}
return userId.ToString();
}
[HttpPost("logout")]
public async Task<ActionResult> logout()
{
await signInManager.SignOutAsync();
return Ok();
}
}
}
If you want to use HttpGet,Here is a demo:
Login:
[HttpGet("login")]
public async Task<IActionResult> Login(InputModel Input) {
return Ok();
}
InputModel:
public class InputModel
{
[Required]
[EmailAddress]
public string Email { get; set; }
[Required]
[DataType(DataType.Password)]
public string Password { get; set; }
[Display(Name = "Remember me?")]
public bool RememberMe { get; set; }
}
View(use method="get" on form):
<form id="account" method="get" asp-controller="Home" asp-action="Login">
<h4>Use a local account to log in.</h4>
<hr />
<div asp-validation-summary="All" class="text-danger"></div>
<div class="form-group">
<label asp-for="Input.Email"></label>
<input asp-for="Input.Email" class="form-control" />
<span asp-validation-for="Input.Email" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Input.Password"></label>
<input asp-for="Input.Password" class="form-control" />
<span asp-validation-for="Input.Password" class="text-danger"></span>
</div>
<div class="form-group">
<div class="checkbox">
<label asp-for="Input.RememberMe">
<input asp-for="Input.RememberMe" />
#Html.DisplayNameFor(m => m.Input.RememberMe)
</label>
</div>
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary">Log in</button>
</div>
</form>
result:
However,when you use HttpGet,your user login infomation will exposed in the url,so it is not safe,you'd better use HttpPost.
If you want to get user detail,you can use this:
var info = await _userManager.GetUserAsync(HttpContext.User);
I have fixed this issues by :
[HttpGet]
[Authorize]
public async Task<object> GetUserProfile()
{
var userName = await userManager.FindByNameAsync(HttpContext.User.Identity.Name);
var userId = userName.Id;
var role = await userManager.GetRolesAsync(userName);
if (User.IsInRole("Staff"))
{
return Ok(new
{
userName,
userId
});
}
return Ok(new
{
userName,
role
});

Categories

Resources