A specified Include path is not valid on eager loading - asp.net-mvc

I am using eager loading in entity framework. My Model class is like
public class EmployeeMaster : AbsCommonParameters
{
[Key]
public int Id { get; set; }
public string EmpId { get; set; }
[Required(ErrorMessage = "Employee name is required")]
public string Name { get; set; }
[Required(ErrorMessage = "Employee geography is required")]
public string Geography { get; set; }
public string EmailId { get; set; }
[DataType(DataType.Date), DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}", ApplyFormatInEditMode = true)]
[Column(TypeName = "Date")]
[Display(Name = "Date Of Joining")]
public Nullable<DateTime> DOJ { get; set; }
[Required(ErrorMessage = "Employee designation is required")]
public string Designation { get; set; }
[NotMapped]
public List<CenterMaster> lstCenters { get; set; }
[NotMapped]
public List<CostCodeMaster> lstCostCode { get; set; }
}
In Controller Index Action my Code is like this
public ActionResult Index()
{
var lstUser = db.ObjEmployeeMaster.Include(p => p.lstCenters).
Include(p => p.lstCostCode).Where(x => x.DeletedStatus == false).ToList();
return View(lstUser);
}
Also In DBContext Constructor I have used
this.Configuration.LazyLoadingEnabled = false;
After this I got error
A specified Include path is not valid
Please help where I am wrong.
Thanks in advance.

Related

MVC Validation - Issue checking DB records for matching values before posting

Hi everyone I cant seem to figure out how to check a record before creating a new post in MVC
When a user creates a "SuperMember" I want it to check IF that "Character" has already been assigned that "membership" already aka a duplicate record. Each Character can have many memberships but not the same one.
Heres my code -
MODELS
public class Character
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int CharacterID { get; set; }
[Required]
[Display(Name = "First Name")]
public string FirstName { get; set; }
[Required]
[Display(Name = "Last Name")]
public string LastName { get; set; }
[Required]
[Display(Name = "Hero Alias")]
public string HeroAlias { get; set; }
[Required]
[Display(Name = "Email Address")]
public string Email { get; set; }
public ICollection<SuperMembers> SuperMembers { get; set; }
}
public class Membership
{
[Key]
public int MembershipID { get; set; }
[Required]
[Display(Name = "Membership Name")]
public string MembershipName { get; set; }
[Required]
[Display(Name = "Membership Tyoe")]
public string Type { get; set; }
public ICollection<SuperMembers>SuperMembers { get; set; }
}
public class SuperMembers
{
[Key]
[Display(Name = "Membership Number")]
public int SuperMembersID { get; set; }
[Required]
[Display(Name = "Hero Alias")]
public int CharacterID { get; set; }
public Character Character { get; set; }
[Required]
[Display(Name = "Membership")]
public int MembershipID { get; set; }
public Membership Membership { get; set; }
[DataType(DataType.Currency)]
[Column(TypeName = "money")]
[Required]
[Display(Name = "Account Balance")]
public decimal AccountBalance { get; set; }
}
Then the Controller POST Method
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("SuperMembersID,CharacterID,MembershipID,AccountBalance")] SuperMembers superMembers)
{
if (ModelState.IsValid)
{
var IfAlreadyExists = dbo.SuperMembers.Where(x => x.CharacterID == CharacterID && x.MembershipID == MembershipName).FirstOrDefault();
if (IfAlreadyExists == null)
{
//POST
}
else
{
//Return ERROR "Sorry this Membership already exists"
}
_context.Add(superMembers);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
ViewData["CharacterID"] = new SelectList(_context.Character, "CharacterID", "HeroAlias", superMembers.CharacterID);
ViewData["MembershipID"] = new SelectList(_context.Membership, "MembershipID", "MembershipName", superMembers.MembershipID);
return View(superMembers);
}
The dbo in "dbo.SuperMembers" is underlined too, im using a local db for this little practice project so not sure if thats also a factor?
Im fairly new to this, this is my first StackOverflow post so apologies if ive missed anything obvious - Would appreciate any pointers. Thanks

MVC Entity Framework Models and Relationships

im quite new to ASP.net and entity framework. I created a class but im just going to simplify it and take the example class from Microsoft. So here we go. These are all the example classes
public class Student
{
public int ID { get; set; }
public string LastName { get; set; }
public string FirstMidName { get; set; }
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public DateTime EnrollmentDate { get; set; }
public virtual ICollection<Enrollment> Enrollments { get; set; }
}
public class Instructor
{
public int ID { get; set; }
[Required]
[Display(Name = "Last Name")]
[StringLength(50)]
public string LastName { get; set; }
[Required]
[Column("FirstName")]
[Display(Name = "First Name")]
[StringLength(50)]
public string FirstMidName { get; set; }
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
[Display(Name = "Hire Date")]
public DateTime HireDate { get; set; }
[Display(Name = "Full Name")]
public string FullName
{
get { return LastName + ", " + FirstMidName; }
}
public virtual ICollection<Course> Courses { get; set; }
public virtual OfficeAssignment OfficeAssignment { get; set; }
}
public class OfficeAssignment
{
[Key]
[ForeignKey("Instructor")]
public int InstructorID { get; set; }
[StringLength(50)]
[Display(Name = "Office Location")]
public string Location { get; set; }
public virtual Instructor Instructor { get; set; }
}
public class Course
{
[DatabaseGenerated(DatabaseGeneratedOption.None)]
[Display(Name = "Number")]
public int CourseID { get; set; }
[StringLength(50, MinimumLength = 3)]
public string Title { get; set; }
[Range(0, 5)]
public int Credits { get; set; }
public int DepartmentID { get; set; }
public virtual Department Department { get; set; }
public virtual ICollection<Enrollment> Enrollments { get; set; }
public virtual ICollection<Instructor> Instructors { get; set; }
}
Like i said this is just for a example im trying to get know it.
My First Question: Do you need something like DepartmentID When you already do public virtual Department Department?
Second question: When i have a Collection of data how do i add values or Ids to that collection in the controller i can find this anywhere.
Third Question: Can some one link me a complete MVC example application with proper relationships

DropDownListFor selection not being saved

I am new to MVC. I am using a DropDownListFor to display a list of company names and, based on the selection made, filling in other Customer fields. The customer fields are being populated fine, but when I attempt to POST the record, I get a validation error "Company name is required", even though the company name has been selected in the DropDownListFor. Here is the ViewModel:
namespace CMSUsersAndRoles.Models
{
public class QuoteViewModel
{ [Key]
[Display(Name = "Quote Id")]
public int QuoteId { get; set; }
// Columns from Customer table
[Required(ErrorMessage = "Please select a company")]
[Display(Name = "Customer Id")]
public int? CustomerId { get; set; }
[Display(Name = "Sales Rep")]
public string SalesRep { get; set; }
[Display(Name = "First Name")]
public string FirstName { get; set; }
[Display(Name = "Last Name")]
public string LastName { get; set; }
[Required]
public string Company { get; set; }
[Display(Name = "Address 1")]
public string Address1 { get; set; }
[Display(Name = "Address 2")]
public string Address2 { get; set; }
public string City { get; set; }
public string State { get; set; }
[StringLength(10)]
[Display(Name = "Zip Code")]
[RegularExpression(#"^\d{5}(-\d{4})?$", ErrorMessage = "Invalid Zip Code")]
public string PostalCode { get; set; }
[Phone]
[Display(Name = "Work Phone")]
public string WorkPhone { get; set; }
[Phone]
[Display(Name = "Cell Phone")]
public string CellPhone { get; set; }
[EmailAddress]
public string Email { get; set; }
[Range(0, 100)]
public decimal? Discount { get; set; }
[Display(Name = "Payment Terms")]
public int? PaymentTerms { get; set; }
// Columns from QuoteDetail table
[Display(Name = "Quote Detail")]
public List<QuoteDetail> QuoteDetail { get; set; }
// Columns from Quote table
public decimal Subtotal { get; set; }
public decimal Tax { get; set; }
public decimal Total { get; set; }
[DataType(DataType.Date)]
[Display(Name = "Quote Date")]
public DateTime? QuoteDate { get; set; }
[DataType(DataType.Date)]
[Display(Name = "Good Until")]
public DateTime? GoodUntil { get; set; }
[DataType(DataType.Date)]
[Display(Name = "Quote Sent")]
public DateTime? QuoteSent { get; set; }
[DataType(DataType.Date)]
[Display(Name = "Date Approved")]
public DateTime? DateApproved { get; set; }
[DataType(DataType.Date)]
[Display(Name = "Date Ordered")]
public DateTime? DateOrdered { get; set; }
}
}
Here is the code from the View:
#Html.DropDownListFor(model => model.CustomerId, new SelectList(ViewBag.Customers, "CustomerId", "Company"), "---Select one---", new { htmlAttributes = new { #class = "company" } });
#Html.HiddenFor(model => model.Company)
#Html.ValidationMessageFor(model => model.Company, "", new { #class = "text-danger" })
Here is the Get:
public ActionResult Create()
{
QuoteViewModel qvm = new QuoteViewModel();
var customers = db.Customers.ToList();
ViewBag.Customers = customers;
return View(qvm);
}
And here is the code for the POST:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(QuoteViewModel qvm)
{
if (ModelState.IsValid)
{
Quote quote1 = new Quote();
quote1.CustomerId = qvm.CustomerId;
...
customer.CustomerId = (int)qvm.CustomerId;
...
customer.Company = qvm.Company;
db.Entry(customer).State = EntityState.Modified;
try
{
db.SaveChanges();
}
catch (DbUpdateConcurrencyException ex)
{
var objContext = ((IObjectContextAdapter)db).ObjectContext;
// Get failed entry
var entry = ex.Entries.Single();
// Now call refresh on ObjectContext
objContext.Refresh(RefreshMode.ClientWins, entry.Entity);
}
return RedirectToAction("Index");
}
var customers = db.Customers.ToList();
ViewBag.Customers = customers;
return View(qvm);
}
What am I missing? Any help will be much appreciated.
I was not setting the value of the HiddenFor below. Thanks, #StephenMuecke.
#Html.HiddenFor(model => model.Company)

Excluding properties from a viewmodel

I have a viewmodel that contains a CustomerModel e.g.
public class MyAccountViewModel
{
public CustomerModel Customer { get; set; }
public LoginModel Login { get; set; }
public ICollection<AuthenticationClientData> Clients { get; set; }
public bool HasLocalPassword { get; set; }
public LocalPasswordModel Password { get; set; }
}
[DataContract]
public class CustomerModel
{
[DataMember]
public Guid CustomerBusinessId { get; set; }
[DataMember(IsRequired = true)]
[Required(ErrorMessage = "First Name is required")]
[Display(Name = "First Name")]
public string FirstName { get; set; }
[DataMember(IsRequired = true)]
[Required(ErrorMessage = "Last Name is required")]
[Display(Name = "Last Name")]
public string LastName { get; set; }
[DataMember]
public string FullName
{
get { return string.Format("{0} {1}", FirstName, LastName); }
}
[DataMember]
public string Identity { get; set; }
[DataMember(IsRequired = true)]
[Required(ErrorMessage = "Email is required")]
public string Email { get; set; }
[DataMember]
[Display(Name = "Birth Date")]
public DateTime? BirthDate { get; set; }
[DataMember]
public string Mobile { get; set; }
[DataMember]
public string Phone { get; set; }
[DataMember]
public string Twitter { get; set; }
[DataMember]
[Display(Name = "Facebook")]
public string FaceBook { get; set; }
[DataMember]
public string WebSite { get; set; }
[DataMember]
public string Blog { get; set; }
}
My CustomerModel object contains a property "CustomerBusinessId" is it possible for my viewmodel to exclude this property so I am only returning the required fields to the view?

AutoMapper and required fields

I am trying to create a new record using only some of the fields in my Domain Model. I have created a ViewModel for this and am using AutoMapper.
My code is failing at the minute due to the required fields that I have on my Domain Model. I have added opt=>opt.Ignore() on the necessary field however, I am still having problems.
When I remove [Required] from the StaffPresent field the record is added to the DB.
In my Global.asax.cs
Mapper.CreateMap<CustomerSupportRecord, CustomerSupportRecordForCreation>();
Mapper.CreateMap<CustomerSupportRecordForCreation, CustomerSupportRecord>().ForMember(p=>p.StaffPresent, opt=>opt.Ignore());
Domain Model
public class CustomerSupportRecord
{
public int CustomerSupportRecordID { get; set; }
[Required]
public int CustomerID { get; set; }
[Required]
public string EmployeeID { get; set; }
[Required(ErrorMessage = "Please enter a Date")]
[DataType(DataType.Date)]
[Display(Name = "Date")]
public DateTime Date { get; set; }
[Required(ErrorMessage = "Please select an Arrival Time")]
[DataType(DataType.Time)]
[Display(Name = "Arrival")]
public DateTime ArrivalTime { get; set; }
[DataType(DataType.Time)]
[Display(Name = "Departure")]
public DateTime? DepartureTime { get; set; }
[Required(ErrorMessage = "Please select a Type")]
[Display(Name = "Type")]
public int CustomerSupportTypeID { get; set; }
[Required(ErrorMessage = "Please enter the staff who were present at the Feedback")]
[Display(Name = "Staff Present at Feedback")]
public string StaffPresent { get; set; }
[Display(Name = "Setting")]
public string ReflectionSetting { get; set; }
[Display(Name = "Advisor")]
public string ReflectionAdvisor { get; set; }
[Display(Name = "Notes")]
public string Notes { get; set; }
[Display(Name = "Comments")]
public string Comments { get; set; }
// Navigation Properties
public virtual Customer Customer { get; set; }
public virtual CustomerSupportType CustomerSupportType { get; set; }
public virtual Employee Employee { get; set; }
}
ViewModel
public class CustomerSupportRecordForCreation
{
public int CustomerSupportRecordID { get; set; }
public int CustomerID { get; set; }
public string EmployeeID { get; set; }
[DataType(DataType.Date)]
[Display(Name = "Date")]
public DateTime Date { get; set; }
[DataType(DataType.Time)]
[Display(Name = "Arrival")]
public DateTime ArrivalTime { get; set; }
[Display(Name = "Type")]
public int CustomerSupportTypeID { get; set; }
[Display(Name = "Notes")]
public string Notes { get; set; }
}
And finally my Controller
//
// GET: /CustomerSupport/CustomerSupportRecord/Create
public ActionResult Create()
{
ViewBag.CustomerSupportTypeID = new SelectList(db.CustomerSupportType, "CustomerSupportTypeID", "CustomerSupportTypeName");
var model = new CustomerSupportRecordForCreation { CustomerID = 1, EmployeeID = "20213" };
return View("Create", model);
}
//
// POST: /CustomerSupport/CustomerSupportRecord/Create
[HttpPost]
public ActionResult Create(CustomerSupportRecordForCreation customersupportrecord)
{
if (ModelState.IsValid)
{
var newRecord = Mapper.Map<CustomerSupportRecordForCreation, CustomerSupportRecord>(customersupportrecord);
db.CustomerSupportRecord.Add(newRecord);
db.SaveChanges();
return RedirectToAction("Index");
}
ViewBag.CustomerSupportTypeID = new SelectList(db.CustomerSupportType, "CustomerSupportTypeID", "CustomerSupportTypeName", customersupportrecord.CustomerSupportTypeID);
return View(customersupportrecord);
}
AutoMapper's configuration doesn't have anything to do with validation attributes, it just specifies the rules for how to map objects between each-other.
In your case, the mapping:
Mapper.CreateMap<CustomerSupportRecordForCreation, CustomerSupportRecord>().ForMember(p=>p.StaffPresent, opt=>opt.Ignore());
tells AutoMapper not to copy the StaffPresent property.
If your database model has a [Required] attribute, you'll still need to set that data elsewhere.
One thing to note based on your comment, it's a good idea to add validation to your ViewModels, as it prevents you from calling your database methods with improper data, gives you client side validation, and lets you enforce different constraints than your model might require.

Resources