There is no ViewData item of type 'IEnumerable<SelectListItem>' that has the key 'Dept_IDs' - model-view-controller

The dropdown works fine. It fetches the values from the database but when i insert the selected value into a table. It gives me the error, tried a lot of different ways but didn't work.
View:
#Html.DropDownList(model => model.Dept_ID, ViewBag.deptlistname as
SelectList, "Please select a department");
Controllers:
public ActionResult UserRegistration()
{
HREntities4 db = new HREntities4();
var getdeptlist = db.departments.ToList();
SelectList list = new SelectList(getdeptlist, "Dept_ID",
"Dept_ID");
ViewBag.deptlistname = list;
return View();
}
Post:
[HttpPost]
public ActionResult UserRegistration(UserRegistration model)
{
if (ModelState.IsValid)
{
var details = new HREntities4();
details.logins.Add(new login{
FirstName = model.FirstName,
LastName = model.LastName,
Username = model.Username,
Email = model.Email,
Password = model.Password,
PhoneNumber =model.PhoneNumber,
Address = model.Address,
Hire_Date = model.Hire_Date,
Salary = model.Salary,
Dept_ID = model.Dept_ID
});
details.SaveChanges();
ModelState.AddModelError("updated", "User has been registered");
}
return View();
}
ViewModel:
public partial class UserRegistration
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Username { get; set; }
public string Email { get; set; }
public string Password { get; set; }
public string PhoneNumber { get; set; }
public string Address { get; set; }
public string Hire_Date { get; set; }
public Nullable<double> Salary { get; set; }
public int Dept_ID { get; set; }
}

Remove the 's' from Dept_IDs because in your UserRegistration model you have Dept_ID.

Related

I cannot add the orders to the database

I am building an e-store with ASP.NET Core. I've created CRUD operations to add my products and save it to the database, it is working fine. Then I wanted to save the orders from the customers to my database, sadly I couldn't manage to do so.
When I click a button, it saves the order to the database and sends the customer to the thank you page.
Can you please check my code and tell me where am going wrong.
This is my OrderController:
[HttpPost]
public async Task<IActionResult> PlaceOrder([FromBody] Order model)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
var order = new Order
{
OrderDate = DateTime.Now,
Name = model.Name,
Address = model.Address,
Email = model.Email,
PhoneNo = model.PhoneNo
};
var orderDetails = new List<OrderDetails>();
foreach (var item in model.OrderDetails)
{
orderDetails.Add(new OrderDetails
{
ProductId = item.ProductId,
// Quantity = item.Quantity,
// Price = item.Price,
Order = order
});
}
using (var context = new AppDbContext(_dbContextOptions))
{
context.Order.Add(order);
context.OrderDetails.AddRange(orderDetails);
await context.SaveChangesAsync();
}
// returns a HTTP 200 OK response to the client indicating that the operation was successful.
return Ok();
}
and this is the button from my view:
<p>
<a asp-controller="Order" asp-action="PlaceOrder" class="btn btn-primary addToCart">Place my order</a>
</p>
Order class:
public class Order
{
public Order()
{
OrderDetails = new List<OrderDetails>();
}
public int Id { get; set; }
[Display(Name = "Order No")]
public string OrderNo { get; set; }
[Required]
public string Name { get; set; }
[Required]
[Display(Name = "Phone Number")]
public string PhoneNo { get; set; }
[Required]
[EmailAddress]
public string Email { get; set; }
[Required]
public string Address { get; set; }
[Display(Name = "Today's Date")]
public DateTime OrderDate { get; set; }
public virtual List<OrderDetails> OrderDetails { get; set; }
}
Order details class
public class OrderDetails
{
public int Id { get; set; }
[Display(Name = "Order")]
public int OrderId { get; set; }
[Display(Name = "Product")]
public int ProductId { get; set; }
[ForeignKey("OrderId")]
public Order Order { get; set; }
[ForeignKey("PorductId")]
public Product Product { get; set; }
}

Linq adding items to list in the query

Good day,
I have one problem. I have three Domain objects
public class User
{
public Guid Id { get; set; }
public string Username { get; set; }
public string EmailAddress { get; set; }
public string Password { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
[NotMapped]
public List<string> Roles { get; set; }
//nav prop
public List<User_Role> UserRoles { get; set; }
}
public class User_Role
{
public Guid Id { get; set; }
public Guid UserId { get; set; }
//nav prop
public User User { get; set; }
public Guid RoleId { get; set; }
//nav prop
public Role Role { get; set; }
}
public class Role
{
public Guid Id { get; set; }
public string Name { get; set; }
public List<User_Role> UserRoles { get; set; }
}
I want to create DTO object from them
public class ReturnUserDto
{
public Guid Id { get; set; }
public string Username { get; set; }
public string EmailAddress { get; set; }
public string Password { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public List<string> Roles { get; set; }
}
I have created a controller for it
[Route("api/[controller]")]
[ApiController]
public class UserController : ControllerBase
{
public readonly IUserRepository _userRepository;
public readonly IRoleRepository _roleRepository;
public readonly IUserRoleRepository _userRoleRepository
public UserController(IUserRepository userRepository, IRoleRepository IRoleRepository,
IUserRoleRepository userRoleRepository)
{
_userRepository = userRepository;
_roleRepository = IRoleRepository;
_userRoleRepository = userRoleRepository;
}
[HttpGet]
public async Task<IActionResult> GetAllUsersAsync()
{
var users = _userRepository.GetAllAsync();
var usersDto = users.ConvertToDto(unknow arguments)
}
}
And i am trying achieve it by using static DtoConverstion function
It looks like this
public static IEnumerable<ReturnUserDto> ConvertToDto(this IEnumerable<User> users,
IEnumerable<Role> Role)
{
var returnUserDto = (from user in users
select new ReturnUserDto
{
Id = user.Id,
Username = user.Username,
EmailAddress = user.EmailAddress,
Password = user.Password,
FirstName = user.FirstName,
LastName = user.LastName,
Roles = ?(Something like Role.name)
})
}
How do I achieve it? I understand that I need to use user_roles to get roles from it for a specific user, then add it to DtoConvertion function. I am just not sure how to do it.
Can do it multiple ways.One way is to use the Include() and ThenInclude() option
Instead of _userRepository.GetAllAsync(), add a new method which will get the list of Users along with User Roles and its Roles with it. It will be something like
context.Users
.Include(u => u.UserRoles)
.ThenInclude(u => u.Role).ToList()
Then, in the convert method, something like
public static IEnumerable<ReturnUserDto> ConvertToDto(this IEnumerable<User> users)
{
var returnUserDto = (from user in users
select new ReturnUserDto
{
Id = user.Id,
Username = user.Username,
EmailAddress = user.EmailAddress,
Password = user.Password,
FirstName = user.FirstName,
LastName = user.LastName,
Roles = user.UserRoles.Select(s => s.Role.Name).ToList()
})
}
Refer https://learn.microsoft.com/en-us/ef/ef6/querying/related-data if you are not familiar with the Include() method.
Hope this helps.

.net core ef saving related data results in error SqlException: Cannot insert explicit value for identity column in table

Following this guide, I have tried to do the same in my web app:
var content = new Content()
{
IsActive = true,
Link = new Link()
{
DateCreated = DateTime.UtcNow,
LinkName = model.Name,
LinkDesc = model.Description,
LinkPath = model.LinkPath,
IsActive = true
}
};
_context.Contents.Add(content);
_context.SaveChanges();
This throws an error:
SqlException: Cannot insert explicit value for identity column in
table 'Links' when IDENTITY_INSERT is set to OFF.
But it works if I do this:
var content = new Content() {
IsActive = true
}
_context.Contents.Add(content);
_context.SaveChanges();
var link = new Link()
{
DateCreated = DateTime.UtcNow,
LinkName = model.Name,
LinkDesc = model.Description,
LinkPath = model.LinkPath,
IsActive = true,
ContentId = content.ContentId
};
_context.Links.Add(link);
_context.SaveChanges();
content.LinkId = link.LinkId;
_context.SaveChanges();
These are the models:
public class Content
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int ContentId { get; set; }
public int? LinkId { get; set; } = null;
[ForeignKey("LinkId")]
public virtual Link Link { get; set; }
public DateTime DateCreated { get; set; } = DateTime.UtcNow;
public bool IsActive { get; set; }
}
public class Link
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int LinkId { get; set; }
[MaxLength(300)]
public string LinkDesc { get; set; }
[MaxLength(50)]
[Required]
public string LinkName { get; set; }
public DateTime DateCreated { get; set; } = DateTime.UtcNow;
public bool IsActive { get; set; }
[MaxLength(500)]
public string LinkPath { get; set; }
public int ContentId { get; set; }
[ForeignKey("ContentId")]
public virtual Content Content { get; set; }
}
Am I missing anything? Why would the first code try to insert a value to LinkId?

Trouble with Model.IsValid on a property thats not required

I am having trouble with Model.IsValid on a property that's not required.
Here's the code.
BeginForm in the Edit.cshtml file
#using (Html.BeginForm("Edit", "Member", FormMethod.Post, new { enctype = "multipart/formdata" }))
{
#Html.Partial("_MemberForm", Model.Member)
}
MemberEditViewModel: (used for the Edit.cshtml file)
public class MemberEditViewModel
{
public MemberFormModel Member { get; set; }
}
MemberFormModel:
public class MemberFormModel : ICreateMemberCommand, IValidatableObject
{
public int Id { get; set; }
[Required]
public string FirstName { get; set; }
[Required]
public string LastName { get; set; }
[Required]
public string SocialSecurityNumber { get; set; }
[Required]
public int PinCode { get; set; }
[Required]
public char Gender { get; set; }
public string Email { get; set; }
[Required]
public string Address { get; set; }
[Required]
public string ZipCode { get; set; }
[Required]
public string ZipAddress { get; set; }
public string Phone { get; set; }
public string Phone2 { get; set; }
[Required]
public string City { get; set; }
[Required]
public int CountryId { get; set; }
//not required (but still displaying error it's required)
public Membership Membership { get; set; }
// not required (displaying error it's required)
public PunchCard PunchCard { get; set; }
public bool IsActive { get; set; }
block of _MemberForm.cshtml (partial)
<fieldset>
<dl>
<dt>#Html.LabelFor(m => m.Id)</dt>
<dd>#Html.TextBoxFor(m => m.Id, new { disabled = "disabled", #readonly = "readonly" })</dd>
<dt>#Html.LabelFor(m => m.PinCode)</dt>
<dd>#Html.EditorFor(m => m.PinCode)</dd>
<!-- problem with membership, maybe with the .FromData/ToDate ? -->
<dt>#Html.LabelFor(m => m.Membership)</dt>
<dd>#Html.EditorFor(m => m.Membership.FromDate, new { #name = "Membership" }) -
#Html.EditorFor(m => m.Membership.ToDate, new { #name="Membership"})</dd>
<!-- problem with punch card, maybe with the .Times ? -->
<dt>#Html.LabelFor(m => m.PunchCard)</dt>
<dd>#Html.EditorFor(m => m.PunchCard.Times, new { #name = "PunchCard" })</dd>
</dl>
</fieldset>
The MemberController Edit Action
// POST: /Members/10002/Edit
[HttpPost]
public ActionResult Edit(FormCollection formValues, MemberFormModel memberForm)
{
var errors = ModelState.Values.SelectMany(v => v.Errors);
if(IsSaveOperation(formValues)){
if(TryUpdateMember(memberForm)){
return RedirectToAction("Details", "Member", new {id = memberForm.Id});
}
}
var mm = new MemberEditViewModel{ Member = memberForm };
return View(mm);
}
Membership.cs
public class Membership
{
public Membership(){ /* empty constructor */}
public Membership(int id, int memberId, DateTime fromDate, DateTime toDate)
{
Id = id;
MemberId = memberId;
FromDate = fromDate;
ToDate = toDate;
}
public int Id { get; set; }
public int MemberId { get; set; }
[DataType(DataType.Date)]
public DateTime FromDate { get; set; }
[DataType(DataType.Date)]
public DateTime ToDate { get; set; }
}
PunchCard.cs
public class PunchCard
{
public PunchCard() { /* empty constructor */ }
public PunchCard(int memberId, int times, DateTime createdDate, DateTime modifiedDate)
{
this.MemberId = memberId;
this.Times = times;
this.CreatedDate = createdDate;
this.ModifiedDate = modifiedDate;
}
public int Id { get; set; }
public int MemberId { get; set; }
public int Times { get; set; }
public DateTime CreatedDate { get; set; }
public DateTime ModifiedDate { get; set; }
}
You see I dont have any [Required] attribute, neither in the MemberFormModel. So how come those two are Required ? Its a mystery.
You should not be using both the disabled and readonly attribute on your textbox:
#Html.TextBoxFor(m => m.Id, new { disabled = "disabled", #readonly = "readonly" })
I guess the disabled attribute takes precedence and the value of the Id is never sent to the server when you submit the form. That's why you get a modelstate error. Because your id property is required. Now you will be probably tell me that it is not decorated with the [Required] attribute but this doesn't matter. Since you have declared it as a non-nullable integer it is implicitly required and the framework automatically makes it required. If you don't want this to happen you should declare it as a nullable integer.
So back to your view, if you want to only display id, without allowing the user to modify it, use readonly:
#Html.TextBoxFor(m => m.Id, new { #readonly = "readonly" })
Obviously don't think that if you made a textbox readonly, the user cannot modify it. The normal user will not. But a hacker could always put whatever value he wants in this textbox and forge a request. So absolutely do not rely on this as some sort of security or something.

How to display a custom string in mvc3 dropdownlist but keep id field mapped to item selected?

Q: How can I display firstname + lastname (or any string literal) in a mvc3 dropdown list but keep mapped/bound associated id when item is selected?
-- Model
public class UserT
{
public int UserTId { get; set; }
public string Username { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
-- Controller
// This is what I have to display as username but want to display as FirstName + LastName
// .: How to I change "Username" to FirstName + LastName but bind it to the selected UserTId ???
ViewBag.ContactUserId = new SelectList(db.UserTs, "UserTId", "Username");
-- View
#Html.DropDownList("ContactUserId", "--Select a contact--")
One possibility would be to add a new, read-only property to your UserT class which returns the first and last names and then bind to that property:
public class UserT
{
public int UserTId { get; set; }
public string Username { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string FullName {
get { return string.Format("{0} {1}", this.FirstName, this.LastName); }
}
}
ViewBag.ContactUserId = new SelectList(db.UserTs, "UserTId", "FullName");

Resources