I am new to MVC. I am trying to create CRUD for Engineer entity for which I have written following modal class.
public abstract class Person
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[Required(ErrorMessage="first name required")]
[MaxLength(50)]
[DisplayName("First Name")]
public string FirstName { get; set; }
[MaxLength(50)]
[DisplayName("Middle Name")]
public string MiddletName { get; set; }
[Required(ErrorMessage = "last name required")]
[MaxLength(50)]
[DisplayName("Last Name")]
public string LasttName { get; set; }
}
public class Engineer : Person
{
[Required]
[MaxLength(50)]
[DisplayName("Qualification")]
public string Qualification { get; set; }
public Address Address { get; set; }
}
Now When I add controller for the Engineer with read/write actions and views with entity framework, my Views(Create/Index/Delete/Details/Edit) for Engineer does include Address class fields. But when I run the project I could see address fields in Engineer Table in backend. where am I getting wrong.
Related
I have two Controllers and their views. The first controller is the applicant controller, In this applicant controller, I have the "add applicant" form. This form link is given to the Second controller(vacancycontroller) view. Now I want to get data on the vacancy positions when I click on the button. Is this possible?
public class Application : IVacancy, IStage
{
[Key]
public int? Id { get; set; }
[Required]
[MinLength(2)]
[MaxLength(50)]
public string FirstName { get; set; }
public string MiddleName { get; set; }
[Required]
public string LastName { get; set; }
[Required]
[EmailAddress]
public string Email { get; set; }
public string Phone { get; set; }
public string Gender { get; set; }
public string Address { get; set; }
public int? Experience { get; set; }
public string Status { get; set; }
public string Resume { get; set; }
[Display(Name = "Vacancy")]
public int? VacancyId { get; set; }
[Display(Name = "Stage")]
public int? StageId { get; set; }
public DateTime DateCreated { get; set; }
[ForeignKey("VacancyId")]
public virtual Vacancy Vacancy { get; set; }
}
This is my application entity.
public interface IVacancy
{
public int? VacancyId { get; set; }
public Vacancy Vacancy { get; set; }
}
[Table("vacancy")]
public class Vacancy
{
[Key]
public int? Id { get; set; }
[Required]
[MinLength(2)]
[MaxLength(50)]
public string Position { get; set; }
[Required]
public string Skills { get; set; }
}
And this is vacancy entity.
When I open the vacancy page and click on add applicant, In add applicant form, VaacancyId Text box fills with the Position of that particular row.This is vacancy page img
I have two classes, Company and CompanyAddress.
For every Company there can be multiple CompanyAddresses, such as Invoice address and correspondence address.
Via entity framework, I'm trying to include all CompanyAddresses that belong the Company. However, I keep getting the following debug error:
An exception of type 'System.InvalidOperationException' occurred in System.Data.Entity.dll but was not handled in user code
Additional information: A specified Include path is not valid. The EntityType 'StatelyTechAdmin.Models.Company' does not declare a navigation property with the name 'CompanyAddresses'.
Can anyone advise me on why I cannot include all addresses in my LINQ query? Please note I am very new to Entity Framework.
Company Class
public class Company
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public virtual long CompanyId { get; set; }
[Required]
[Display(Name = "Company Name")]
public virtual string Name { get; set; }
public virtual DateTime CreatedDate { get; set; }
public virtual IEnumerable<CompanyAddress> CompanyAddresses { get; set; }
}
CompanyAddress Class
public class CompanyAddress
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public virtual long CompanyAddressId { get; set; }
[Required]
public virtual long CompanyId { get; set; }
[ForeignKey("CompanyId")]
public virtual Company Company { get; set; }
[Required]
public virtual int CompanyAddressTypeId { get; set; }
[ForeignKey("CompanyAddressTypeId")]
public virtual CompanyAddressType CompanyAddressType { get; set; }
[Display(Name = "Address 1")]
public virtual string Address1 { get; set; }
[Display(Name = "Address 2")]
public virtual string Address2 {get; set; }
[Display(Name = "Town")]
public virtual string Town { get; set; }
[Display(Name = "City")]
public virtual string City { get; set; }
[Required]
public virtual long CountyId { get; set; }
[ForeignKey("CountyId")]
[Display(Name = "County")]
public virtual County County { get; set; }
[Required]
[Display(Name = "Postal Code")]
public virtual string PostalCode { get; set; }
public virtual DateTime CreatedDate { get; set; }
}
Calling Method from MVC Action
public ActionResult Index()
{
var comp = db.Companies.Include(a => a.CompanyAddresses).ToList();
return View(comp);
}
All advice welcome! Thank you for your time.
You can't use IEnumerable for your navigation property. You need to use ICollection or a type derived from it.
How do I load related entities of type IEnumerable<T>
I am building a web application using MVC 3. It has users with different roles and privileges. I am using EF Code First approach for database creation. My model class for user is:
public class Users
{
public int UserID { get; set; }
public Name Name { get; set; }
public Address Address { get; set; }
public Contact Contact { get; set; }
}
public class Name
{
[Required, MaxLength(50), Display(Name = "First Name"), Column("FirstName")]
public string FirstName { get; set; }
[MaxLength(50), Display(Name = "Middle Name"), Column("MiddleName")]
public string MiddleName { get; set; }
[Required, MaxLength(50), Display(Name = "Last Name"), Column("LastName")]
public string LastName { get; set; }
}
public class Address
{
[Required, MaxLength(50), Display(Name = "Street"), Column("Street")]
public string Street { get; set; }
[Required, MaxLength(50), Display(Name = "City"), Column("City")]
public string City { get; set; }
[Required, MaxLength(50), Display(Name = "Country"), Column("Country")]
public string Country { get; set; }
[Required, MaxLength(5), Display(Name = "Postal Code"), Column("PostalCode")]
public string PostalCode { get; set; }
}
public class Contact
{
[Required, MaxLength(50), Display(Name = "Email"), Column("Email")]
public string Email { get; set; }
[Required, MaxLength(50), Display(Name = "Phone"), Column("Phone")]
public string Phone { get; set; }
[Required, MaxLength(50), Display(Name = "Fax"), Column("Fax")]
public string Fax { get; set; }
}
But for roles and authentication I want to use the default aspnetdb.mdf of App_Data folder. How do I link my Users table with the default Users table of aspnetdb.mdf?
Since it seems like you are creating a new site and DB, I wouldn't go about it this way, unless you have to for whatever reason.
I would use UserProfile to store additional info like address, phone, fax, etc. for the user, take a look at the Membership User Profile API to add the custom properties.
Also this article may help, it's a bit old but it should help you if needed.
Using this model:
public class Cases
{
//case data model for call center
//implement lists for all related child tables too
[Key]
public int CasesID { get; set; }
public string CaseNumber { get; set; }
[Required(ErrorMessage = "Customer is Required")]
public int CustomerID { get; set; }
public virtual Customer Customer { get; set; }
[MaxLength(50)]
public string UserName { get; set; } //get user name from the aspnet membership
[Required(ErrorMessage = "Case Category is Required")]
public int CaseCategoryID { get; set; }
[Required(ErrorMessage = "Technician is Required")]
public int TechnicianID { get; set; }
public virtual Technician Technicians { get; set; }
[Required(ErrorMessage = "Engine Model is Required")]
public int EngineModelID { get; set; }
public virtual EngineModel EngineModel { get; set; }
[MaxLength(50)]
public string BMSWorkorder { get; set; }
[MaxLength(50)]
[Required(ErrorMessage = "Status is Required")]
public string CaseStatus { get; set; }
[MaxLength(50)]
public string OpenedBy { get; set; }
[Required(ErrorMessage = "Opened Date is Required")]
[DataType(DataType.DateTime)]
public DateTime? OpenedDate { get; set; }
[MaxLength(50)]
public string ClosedBy { get; set; }
[DataType(DataType.DateTime)]
public DateTime? ClosedDate { get; set; }
[MaxLength(50)]
[Required(ErrorMessage="Caller First Name is Required")]
public string CallerFirstName { get; set; }
[MaxLength(50)]
[Required(ErrorMessage = "Caller Last Name is Required")]
public string CallerLastName { get; set; }
[MaxLength(100)]
public string AdditionalContact { get; set; }
[MaxLength(10)]
[Required(ErrorMessage = "Qualified is Required")]
public string Qualified { get; set; }
public string Description { get; set; }
[MaxLength(50)]
[Required(ErrorMessage = "ESN is Required")]
public string ESN { get; set; }
[MaxLength(50)]
[Required(ErrorMessage = "Mileage is Required")]
public string Mileage { get; set; }
[DataType(DataType.Date)]
public DateTime? DateInService { get; set; }
[MaxLength(50)]
public string ESTR { get; set; }
[MaxLength(50)]
[Required(ErrorMessage = "EDS is Required")]
public string EDS { get; set; }
[MaxLength(50)]
public string GensetSerialNumber { get; set; }
[MaxLength(50)]
public string GensetModelNumber { get; set; }
//child Case Notes records
public virtual ICollection<CaseNotes> CaseNotes { get; set; }
//child case attachment records
public virtual ICollection<Attachment> Attachments { get; set; }
//child case complaint records
public virtual ICollection<CaseComplaint> CaseComplaint { get; set; }
//tracking fields
public DateTime? CreatedOn { get; set; }
[MaxLength(50)]
public string CreatedBy { get; set; }
public DateTime? ModifiedOn { get; set; }
[MaxLength(50)]
public string ModifiedBy { get; set; }
}
I am wondering why even though only some of the properties are marked required, the modelstate does not get set valid unless all properties have values when saving.
Am I doing something wrong?
EDIT
Here are my razor elements for the dropdownlist fields in question:
#Html.DropDownList("Qualified", String.Empty)
#Html.ValidationMessageFor(model => model.Qualified)
#Html.DropDownList("EngineModelID", String.Empty)
#Html.ValidationMessageFor(model => model.EngineModelID)
#Html.DropDownList("CaseCategoryID", String.Empty)
#Html.ValidationMessageFor(model => model.CaseCategoryID)
The EngineModelID and CaseCategoryID properties must be nullable integers on your view model if you want to allow empty values. Oooops, you are not using view models.
ASP.NET MVC automatically makes non-nullable types required. You could disable this explicitly in your Application_Start:
DataAnnotationsModelValidatorProvider.AddImplicitRequiredAttributeForValueTypes = false;
But if you want to do the things properly you should use view models.
The following is absolutely horrible:
#Html.DropDownList("CaseCategoryID", String.Empty)
I guess you have stuffed a SelectList in a ViewBag.CaseCategoryID so the CaseCategoryID does 2 things at the same time: it represents a list and a selected scalar value.
With view models you would use the strongly typed version of those helpers:
#Html.DropDownListFor(x => x.CaseCategoryID, Model.CaseCategories)
where CaseCategories will be an IEnumerable<SelectListItem> property on your view model that the controller would populate.
I'm using FluentHTML (from MvcContrib) to layout my HTML mark-up. I want to use eager unobtrusive client-validation provided by jquery.validate library. I got everything working correctly except for properties of nested ViewModels. Example:
public class RegisterPageViewModel
{
[Required(ErrorMessage = "First Name cannot be empty.")]
public string FirstName { get; set; }
[Required(ErrorMessage = "Last Name cannot be empty.")]
public string LastName { get; set; }
[Required(ErrorMessage = "Email cannot be empty.")]
[RegularExpression(#"^\w+([-+.']\w+)*#\w+([-.]\w+)*\.\w+([-.]\w+)*$", ErrorMessage = "Invalid Email Format.")]
public string Email { get; set; }
[Required(ErrorMessage = "Password field cannot be empty.")]
[DataType(DataType.Password)]
public string Password { get; set; }
[Required(ErrorMessage = "You have to confirm your password.")]
[Compare("Password", ErrorMessage = "Passwords must match.")]
[DataType(DataType.Password)]
public string PasswordConfirm { get; set; }
[Required]
public AddressDto Address { get; set; }
public bool TermsOfUse { get; set; }
[Required(ErrorMessage = "Nickname is required")]
public string Nickname { get; set; }
public string MiddleName { get; set; }
[Required(ErrorMessage = "Birthdate is required")]
public string Birthdate { get; set; }
public string Phone { get; set; }
[Required(ErrorMessage = "Mobile number is required")]
public string Mobile { get; set; }
public string RakimMelieh { get; set; }
public string ReferralNickname { get; set; }
}
It works perfectly for ALL of the properties except for those inside the Address property, although I decorated the properties of the AddressDto with validation attributes as well:
public class AddressDto
{
public int Id { get; set; }
[Required(ErrorMessage = "Address Name is required.")]
public string Name { get; set; }
public string Country { get; set; }
public string District { get; set; }
public string City { get; set; }
public string Area { get; set; }
[Required(ErrorMessage = "Address Details are required.")]
public string Details { get; set; }
public bool IsDefault { get; set; }
}
The same thing happens for other view models as well where there are nested view models inside them. One thing I noticed when inspecting the input fields FireBug is that they always have the valid class on them, even when they're not really valid (according to the annotations decorating their properties).
Any thoughts how I can solve this problem?