Trouble with Model.IsValid on a property thats not required - asp.net-mvc-3

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.

Related

How to debug AutoMapper "Missing type map configuration or unsupported mapping" error

I have seen plenty of examples of this error occuring, for a wide variety of causes and I have gone through all the causes I can see, but still i get the error, so I am wondering if some one can give some information about what this error actually means, so i can try finding the cause. Here is some code:
Controller:
[HttpPost]
public ActionResult Edit(ProfileViewModel model)
{
if (ModelState.IsValid)
{
var person = new UserAttribute();
person = Mapper.Map<ProfileViewModel, UserAttribute>(model);
db.UserAttribute.Add(person);
db.SaveChanges();
}
View Model
public class ProfileViewModel
{
[Display(Name = "First Name")]
[StringLength(20)]
[Required]
public string FirstName { get; set; }
[Display(Name = "Last Name")]
[StringLength(30)]
[Required]
public string LastName { get; set; }
[Display(Name = "Gender")]
[Required]
public string Gender { get; set; }
[Display(Name = "Date of Birth")]
[DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}", ApplyFormatInEditMode = true)]
public DateTime DOB { get; set; }
[Display(Name = "Hair Color")]
public string HairColor { get; set; }
[Display(Name = "Eye Color")]
public string EyeColor { get; set; }
[Display(Name = "Body Type")]
public string Weight { get; set; }
[Display(Name = "Height")]
public string HeightFeet { get; set; }
public string HeightInches { get; set; }
public int UserId { get; set; }
public IEnumerable<SelectListItem> WeightList { get; set; }
public IEnumerable<SelectListItem> EyeColorList { get; set; }
public IEnumerable<SelectListItem> HairColorList { get; set; }
public IEnumerable<SelectListItem> HeightFeetList { get; set; }
public IEnumerable<SelectListItem> HeightInchesList { get; set; }
public IEnumerable<SelectListItem> GenderList { get; set; }
}
UserAttribute model:
public int ProfileId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Gender { get; set; }
public System.DateTime DOB { get; set; }
public string HairColor { get; set; }
public string EyeColor { get; set; }
public string HeightFeet { get; set; }
public string Weight { get; set; }
public int UserId { get; set; }
public string HeightInches { get; set; }
Mapping config:
public class AutoMapperConfiguration
{
public static void Configure()
{
Mapper.Initialize(x => x.AddProfile<ViewToDomainMapProfile>());
Mapper.Initialize(x => x.AddProfile<DomainToViewMapProfile>());
}
}
public class ViewToDomainMapProfile : Profile
{
public override string ProfileName
{
get { return "ViewToDomainMapProfile"; }
}
protected override void Configure()
{
Mapper.CreateMap<ProfileViewModel, UserAttribute>()
.ForSourceMember(x => x.GenderList, y => y.Ignore())
.ForSourceMember(x => x.HairColorList, y => y.Ignore())
.ForSourceMember(x => x.EyeColorList, y => y.Ignore())
.ForSourceMember(x => x.WeightList, y => y.Ignore())
.ForSourceMember(x => x.HeightFeetList, y => y.Ignore())
.ForSourceMember(x => x.HeightInchesList, y => y.Ignore());
}
}
and the config is called in the global asax:
AutoMapperConfiguration.Configure();
Using Mapper.AssertConfigurationIsValid(); produces the following exception:
AutoMapper.AutoMapperConfigurationException :
Unmapped members were found. Review the types and members below.
Add a custom mapping expression, ignore, add a custom resolver, or modify the source/destination type
==============================================================================================
ProfileViewModel -> UserAttribute (Destination member list)
----------------------------------------------------------------------------------------------
ProfileId
So, you need to add mapping for ProfileId.
Overall, it's a good practice to use Mapper.AssertConfigurationIsValid(); either in your unit tests (you have them, right?), or after your mapper configuration. It'll display detailed information for such a misconfigurations.
For the viewmodel => userattribute
I noticed that ProfileId is a destination property, but not a source property.
public int ProfileId { get; set; }
Do you need to add code to ingore this destination member?
Other:
I might also suggest using or customizing the automapper to map properties that present that match by name exclusively.
Also, when possible, please avoid model names ending in the word Attritribute as by convention this is used almost exclusively for actual attributes. (my apologies for nitpicking)

Html.DropDownListFor() set default selected value MVC3

I want to set the default selected value in DropDownListFor when the element is created
Data model:
public class CascadingDropDownModel
{
public int? PreviousFirstListId { get; set; }
public int? SelectedFirstListId { get; set; }
public int? SelectedSecondListId { get; set; }
public string FirstTextHint { get; set; }
public string SecondTextHint { get; set; }
public IList<DropDownElement> FirstDropDownData { get; set; }
public IList<DropDownElement> SecondDropDownData { get; set; }
public CascadingDropDownModel()
{
FirstDropDownData = new List<DropDownElement>();
SecondDropDownData = new List<DropDownElement>();
}
}
Partial view (doesn't work):
#Html.DropDownListFor(
m => m.SelectedFirstListId,
new SelectList(Model.FirstDropDownData, "Id", "Name", Model.SelectedFirstListId),
Model.FirstTextHint)
Partial view (work):
#Html.DropDownListFor(
m => m.SelectedFirstListId,
new SelectList(Model.FirstDropDownData, "Id", "Name", 5),
Model.FirstTextHint)
Please, tell me what the problem is?

validation failing on dropdown MVC

I am using code-first with EF. Validation seems to be failing on a dropdown list with the error System.NullReferenceException: Object reference not set to an instance of an object. This happens when I save a record and I intentionally leave controls empty to test the validation. It happens even if the dropdown list itself has a selection.
here is part of my view:
<div class="editor">
#Html.LabelFor(model => model.EmployeeID)
#Html.DropDownListFor(model => model.EmployeeID, new SelectList(Model.Employees, "Value", "Text"))
#Html.ValidationMessageFor(model => model.EmployeeID)
</div>
If I use a textbox validation works:
<div class="editor">
#Html.LabelFor(model => model.EmployeeID)
#Html.TextBoxFor(model => model.EmployeeID, new { style = "width: 250px;" })
#Html.ValidationMessageFor(model => model.EmployeeID)
</div>
here are my Create controller actions:
public ActionResult Create()
{
var e = iEmployeeRepository.GetAll();
var visitorLogViewModel = new VisitorLogViewModel
{
Employees = e.Select(x => new SelectListItem
{
Value = x.EmployeeID,
Text = x.EmployeeName
})
};
return View(visitorLogViewModel);
}
//
// POST: /VisitorLogs/Create
[HttpPost]
public ActionResult Create(VisitorLog visitorlog)
{
if (ModelState.IsValid) {
iVisitorlogRepository.Add(visitorlog);
iVisitorlogRepository.Save();
return RedirectToAction("Search");
} else {
return View();
}
}
And my viewmodel:
public class VisitorLogViewModel
{
public int Id { get; set; }
[Display(Name = "Visitor Name")]
public string VisitorName { get; set; }
[Display(Name = "Company Name")]
public string CompanyName { get; set; }
[Required(ErrorMessage = "Employee ID is required.")]
[Display(Name = "GB Employee")]
public string EmployeeID { get; set; }
[Display(Name = "Visit Reason")]
public string VisitReason { get; set; }
[Display(Name = "Time In")]
public DateTime TimeIn { get; set; }
[Display(Name = "Time Out")]
public DateTime TimeOut { get; set; }
[Display(Name = "GB Employee")]
public string EmployeeName { get; set; }
public IEnumerable Employees { get; set; }
public VisitorLog VisitorLog { get; set; }
}
And my partial model for validation:
[MetadataType(typeof(VisitorLogMetaData))]
public partial class VisitorLog
{
}
public class VisitorLogMetaData
{
[Required(ErrorMessage = "Visitor name is required.")]
[MaxLength(128)]
public string VisitorName { get; set; }
[Required(ErrorMessage = "Company name is required.")]
[MaxLength(128)]
public string CompanyName { get; set; }
[Required(ErrorMessage = "GB Employee is required.")]
[MaxLength(128)]
public string EmployeeID { get; set; }
[Required(ErrorMessage = "Visit reason is required.")]
[MaxLength(254)]
public string VisitReason { get; set; }
[Required(ErrorMessage = "Time in is required.")]
public DateTime TimeIn { get; set; }
[Required(ErrorMessage = "Time out reason is required.")]
public DateTime TimeOut { get; set; }
}
And finally my model:
public partial class VisitorLog
{
public int Id { get; set; }
public string VisitorName { get; set; }
public DateTime TimeIn { get; set; }
public DateTime TimeOut { get; set; }
public string CompanyName { get; set; }
public string EmployeeID { get; set; }
public string VisitReason { get; set; }
// Navigation properties
[ForeignKey("EmployeeID")]
public virtual Employee Employee { get; set; }
}
I read there was a bug in MVC razor regarding the DropDownListFor but I don't know if that applies in my situation. I have tried some of the solutions and they didn't work for me. I am using 4.5 framework.
Thanks.
Edit:
One thing I noticed, when I submit the page and the error stops on the dropdown element:
#Html.DropDownListFor(model => model.EmployeeID, new SelectList(Model.Employees, "Value", "Text"))
the Model in Model.Employees is null, like it is loosing its binding when the page is submited.
Ok, I did some fundemental changes to my classes. First, I changed the post method in my controller. Previously I was passing the model to the post, now I am passing the view model and mapping it to the model before saving via my repository:
//
// POST: /VisitorLogs/Create
[HttpPost]
public ActionResult Create(VisitorLogViewModel visitorLogViewModel)
{
var e = iEmployeeRepository.GetAll();
VisitorLog visitorLog = new VisitorLog();
visitorLog.Id = visitorLogViewModel.Id;
visitorLog.VisitorName = visitorLogViewModel.VisitorName;
visitorLog.CompanyName = visitorLogViewModel.CompanyName;
visitorLog.EmployeeID = visitorLogViewModel.EmployeeID;
visitorLog.TimeIn = visitorLogViewModel.TimeIn;
visitorLog.TimeOut = visitorLogViewModel.TimeOut;
visitorLog.VisitReason = visitorLogViewModel.VisitReason;
visitorLogViewModel.Employees = new SelectList(e, "EmployeeID", "EmployeeName");
if (ModelState.IsValid)
{
iVisitorlogRepository.Add(visitorLog);
iVisitorlogRepository.Save();
return RedirectToAction("Search");
} else {
return View(visitorLogViewModel);
}
}
Next, I had to add the "required" attribute (validation) to the viewmodel:
public class VisitorLogViewModel
{
public int Id { get; set; }
[Required(ErrorMessage = "Visitor name is required.")]
[MaxLength(128)]
[Display(Name = "Visitor Name")]
public string VisitorName { get; set; }
[Required(ErrorMessage = "Company name is required.")]
[MaxLength(128)]
[Display(Name = "Company Name")]
public string CompanyName { get; set; }
[Required(ErrorMessage = "GB Employee is required.")]
[MaxLength(16)]
[Display(Name = "GB Employee")]
public string EmployeeID { get; set; }
[Required(ErrorMessage = "Visit Reason is required.")]
[MaxLength(254)]
[Display(Name = "Visit Reason")]
public string VisitReason { get; set; }
[Display(Name = "Time In")]
public DateTime TimeIn { get; set; }
[Display(Name = "Time Out")]
public DateTime TimeOut { get; set; }
[Display(Name = "GB Employee")]
public string EmployeeName { get; set; }
public SelectList Employees { get; set; }
}
Not sure if that is the most effcient method but everything works now. If someone sees something wrong with this method let me know.

MVC 3 Dropdowns & Multiple Model ViewModel

I'm pretty new to MVC, but I'm trying to set up a two step user registration system. I have an register model and several other models in a viewmodel called Registration. A user will have a profile based on the register model and then they will select a Producer/Distributor/Restaurant/Importer that they are part of, or create a new one of those. My ViewModel that is returned doesn't validate or pickup the values in my dropdownlists. They populate correctly, but on the post they aren't in the vm. Below is my view/controller/and models. I've been searching the net for 2 days with no luck. Also, if you think my method of registration is wacky, let me know. Thanks!
controller:
public class RegistrationController : Controller
{
private vfContext db = new vfContext();
//
// GET: /Registration/
public ActionResult Register()
{
ViewBag.UserTypeID = new SelectList(db.UserTypes, "UserTypeID", "Name");
ViewBag.ProducerID = new SelectList(db.Producers, "ProducerID", "Name");
ViewBag.PublicationID = new SelectList(db.Publications, "PublicationID", "Name");
ViewBag.ImporterID = new SelectList(db.Importers, "ImporterID", "Name");
ViewBag.DistributorID = new SelectList(db.Distributors, "DistributorID", "Name");
ViewBag.RestaurantID = new SelectList(db.Restaurants, "RestaurantID", "Name");
RegistrationViewModel reg = new RegistrationViewModel();
ViewData.Model = reg;
return View("Registration");
}
[HttpPost]
public ActionResult Register(RegistrationViewModel vm)
{
if (ModelState.IsValid)
{
MembershipCreateStatus createStatus;
//email is userid
Membership.CreateUser(vm.Register.Email, vm.Register.Password, vm.Register.Email, null, null, true, null, out createStatus);
if (createStatus == MembershipCreateStatus.Success)
{
Profile current = Profile.GetProfile(vm.Register.Email);
current.FirstName = vm.Register.FirstName;
current.LastName = vm.Register.LastName;
current.Address1 = vm.Register.Address1;
current.Address2 = vm.Register.Address2;
current.City = vm.Register.City;
current.State = vm.Register.State;
current.Postal = vm.Register.Postal;
current.UserTypeID = vm.Register.UserTypeID;
view - i'm having a hard time copying it over, so the issue is with ddls, so here is how I have the user type id one done
#model vf2.Models.RegistrationViewModel
<div class="editor-label">
#Html.LabelFor(model => model.Register.UserTypeID, "User Type")
</div>
<div class="editor-field">
#Html.DropDownList("UserTypeID", String.Empty)
#Html.ValidationMessageFor(m => m.Register.UserTypeID)
</div>
Models:
public class RegistrationViewModel
{
public RegisterModel Register { get; set; }
public Producer Producer { get; set; }
public Distributor Distributor { get; set; }
//public Publication Publication { get; set; }
public Restaurant Restaurant { get; set; }
public Importer Importer { get; set; }
}
Here is my register model.
public class RegisterModel
{
//[Required]
//[Display(Name = "User name")]
//public string UserName { get; set; }
[Required]
[Display(Name = "First Name")]
public string FirstName { get; set; }
[Required]
[Display(Name = "Last Name")]
public string LastName { get; set; }
[Display(Name = "Address")]
public string Address1 { get; set; }
[Display(Name = "Address Cont.")]
public string Address2 { get; set; }
public string City { get; set; }
public string State { get; set; }
public string Postal { get; set; }
public string Country { get; set; }
[DataType(DataType.PhoneNumber)]
public string Phone { get; set; }
public int ProducerID { get; set; }
public int DistributorID { get; set; }
public int PublicationID { get; set; }
public int ImporterID { get; set; }
public int RestaurantID { get; set; }
public virtual Producer Producer{ get; set; }
public virtual Distributor Distributor { get; set; }
public virtual Publication Publication { get; set; }
public virtual Importer Importer { get; set; }
public virtual Restaurant Restaurant { get; set; }
[Required]
public int UserTypeID { get; set; }
public virtual UserType UserType { get; set; }
[Required]
[DataType(DataType.EmailAddress)]
[Display(Name = "Email address")]
public string Email { get; set; }
[Required]
[StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
[DataType(DataType.Password)]
[Display(Name = "Confirm password")]
[Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
public string ConfirmPassword { get; set; }
}
producer model:
public class Producer
{
public int ProducerID { get; set; }
public string Name { get; set; }
public string Address1 { get; set; }
public string Address2 { get; set; }
public string City { get; set; }
public string State { get; set; }
public string Postal { get; set; }
public string Country { get; set; }
[DataType(DataType.PhoneNumber)]
public string Phone { get; set; }
[DataType(DataType.EmailAddress)]
public string Email { get; set; }
public string Website { get; set; }
public string CreatedBy { get; set; }
public DateTime CreatedOn { get; set; }
public string UpdatedBy { get; set; }
public DateTime? UpdatedOn { get; set; }
public Boolean Active { get; set; }
public virtual ICollection<Wine> Wines { get; set; }
}
I think I figured this out by adding a the following to my viewmodel:
public IEnumerable<UserType> UserTypes { get; set; }
public IEnumerable<Producer> Producers { get; set; }
and then this to my view:
#Html.DropDownListFor(m=>m.Register.UserTypeID,new SelectList(Model.UserTypes,"UserTypeID","Name"),"Select account type")

LINQ query not returning all results due to null value on Entity Framework Core only

I have two rows of test data and am able to pull back the first row with no problems but can't get the second row to return. Digging around and testing shows that this is probably due to the AppovedByID column being null in the row that is not being returned. I have looked but can't figure out how to modify my LINQ query so it will return all rows even if the child table can't be linked in due to a null value.
The Query:
public JsonResult ChangeOrders()
{
var ChangeOrdersList = _DbContext.ChangeOrders
.Include(co => co.ApprovalStatus)
.Include(co => co.ApprovedBy)
.Include(co => co.AssignedTo)
.Include(co => co.CreatedBy)
.Include(co => co.CurrentStatus)
.Include(co => co.Impact)
.Include(co => co.Priority)
.Include(co => co.ChangeType)
.Select(co => new ChangeOrderListVM()
{
ApprovalStatus = co.ApprovalStatus.Name,
ApprovedBy = string.Concat(co.ApprovedBy.FirstName, ' ', co.ApprovedBy.LastName),
AssignedTo = string.Concat(co.AssignedTo.FirstName, ' ', co.AssignedTo.LastName),
CreatedBy = string.Concat(co.CreatedBy.FirstName, ' ', co.CreatedBy.LastName),
CurrentStatus = co.CurrentStatus.Name,
DateApproved = co.DateApproved,
DateCompleated = co.DateCompleated,
DateCreated = co.DateCreated,
DateStarted = co.DateStarted,
EstimatedEndDate = co.EstimatedEndDate,
EstimatedStartDate = co.EstimatedStartDate,
ID = co.ID,
Impact = co.Impact.Name,
Name = co.Name,
Priority = co.Priority.Name,
Reason = co.ReasonForChange,
Type = co.ChangeType.Name
}).ToList();
return Json(ChangeOrdersList);
}
ChangeOrders:
public class ChangeOrder
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int ID { get; set; }
public short? ApprovedByUserID { get; set; }
public byte ApprovalStatusID { get; set; }
public short AssignedToUserID { get; set; }
public short CreatedByUserID { get; set; }
public byte CurrentStatusID { get; set; }
public DateTime? DateApproved { get; set; }
public DateTime? DateCompleated { get; set; }
public DateTime DateCreated { get; set; }
public DateTime? DateStarted { get; set; }
public DateTime EstimatedStartDate { get; set; }
public DateTime EstimatedEndDate { get; set; }
public byte ImpactID { get; set; }
public byte PriorityID { get; set; }
public byte TypeID { get; set; }
[Required]
public string Name { get; set; }
[Required]
public string ReasonForChange { get; set; }
[ForeignKey("ApprovalStatusID")]
public ChangeApprovalStatus ApprovalStatus { get; set; }
[ForeignKey("ApprovedByUserID")]
public User ApprovedBy { get; set; }
[ForeignKey("AssignedToUserID")]
public User AssignedTo { get; set; }
[ForeignKey("CreatedByUserID")]
public User CreatedBy { get; set; }
[ForeignKey("CurrentStatusID")]
public ChangeStatus CurrentStatus { get; set; }
[ForeignKey("ImpactID")]
public ChangeImpact Impact { get; set; }
[ForeignKey("PriorityID")]
public ChangePriority Priority { get; set; }
[ForeignKey("TypeID")]
public ChangeType ChangeType { get; set; }
}
Users:
public class User
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public short ID { get; set; }
[Required]
public string ADUserName { get; set; }
[Required]
public string FirstName { get; set; }
[Required]
public string LastName { get; set; }
[Required]
public string Email { get; set; }
[Required]
public string Phone { get; set; }
[Required]
public DateTime LastUpdated { get; set; }
}
EDIT:
This is apparently unique to Entity Framework 7 (AKA Core) as it works fine in EF 6. I am in fact using EF7 and as an additional test I updated a single line
ApprovedBy = string.Concat(co.ApprovedBy.FirstName, ' ', co.ApprovedBy.LastName),
and changed it to this
ApprovedBy = "",
and all the rows are returning so I then tried to do
ApprovedBy = (co.ApprovedByUserID.HasValue) ? string.Concat(co.ApprovedBy.FirstName, ' ', co.ApprovedBy.LastName) : "",
but that give a very odd error:
incorrect syntax near the keyword 'is'
This is a bug in the library. I have reported the bug for fixing in the next version on github

Resources