asp.net-mvcentity-framework-ctp5modelstate

Saving entities with foreign key in ASP.NET MVC


I need some help doing something I am assuming is simple. I am using ASP.net MVC 3 with CodeFirst (CTP5)

I have two entities: Company and Location. A Company can many Locations. The classes are as follows (stripped of all needless info)

public class Company
{    
    public int Id { get; set; }

    [Required]
    public string Name { get; set; }

    public virtual ICollection<Location> Locations { get; set; }
}

public class Location
{
    public int Id { get; set; }

    [Required]
    public string Name { get; set; }

    [Required]
    public virtual Company Company { get; set; }

}

Now in my controller, I only allow creating a Location within the context of a Company, so the Company Id is always passed in (In the View, I show the name of the Company in a read only field, but do not allow the user to change/edit that.

    public ActionResult Create(int companyId)
    {
        Company company = _session.Single<Company>(c => c.Id == companyId);
        Location newLocation = new Location {Company = company};
        return View(newLocation);
    } 

    [HttpPost]
    public ActionResult Create(Location location)
    {
        if (ModelState.IsValid)
        {
            _session.Add<Location>(location);
            _session.CommitChanges();                
            return RedirectToAction("Index");
        } else {
            return View(location);
        }
    }

Now whenever I try to create a new location, the ModelState.IsValid is always false due to the fact that location.Company.Name is not supplied and is a required field on Company. I am never trying to create a new company here, I merely trying to create a location with a reference to the correct company. I don't want to add the Name property to the view just to get the ModelState to validate. How can this be accomplished easily? Should I be passing something different from the view? or to the view?


Solution

  • As i was explaining in my comment, i stumbled upon a small change which makes this work, still think it is a kludge as I dont see why i need to duplicate the child Id paramater, but the best/simplest one I could find that should be easy to update in the future and I will be the first to admit I dont know all (or most) of what there is in CodeFirst.

    I changed the location class from:

    public class Location  
    {      
        public int Id { get; set; }        
    
        [Required]      
        public string Name { get; set; }        
    
        [Required]      
        public virtual Company Company { get; set; }    
    }
    

    To:

    public class Location  
    {      
        public int Id { get; set; }        
    
        [Required]      
        public string Name { get; set; }        
    
        [Required]      
        public int CompanyId { get; set; }
        public virtual Company Company { get; set; }    
    }
    

    Now as far as I can tell, this hasnt changed the database schema at all, but now the only thing which is required on the Location (when validating) is that there is an ID in the CompanyId field, the Company property can be left null (before, it was trying to validate a proper Company since the Company class was required).

    So now when creating a Location, the only thing the view needs to pass back in the CompanyId.

    Anyone see any drawbacks? or a better way?