Complex tabbed form with panels in .NET MVC 3 - asp.net-mvc-3

I'm trying to create some complex form scheme in a .NET MVC 3 project (or so I think). I'll show a wireframe so that you can understand better.
As you can see from the pic above, it's a form to create a new Car Dealership. I can choose from many available car's manufacturers (in the Add a tab), and each selection creates a new tab in the panel underneath it. In each panel there's a html fieldset, and I can add some new cars on it.
In the end, I want to submit all the form, which comprehends the data from the dealership (e.g. name), the car's brands that it has and the cars available for each brand. How can I do it with MVC 3? I don't know how exactly should I instantiate the model Car Dealership and its respective View. What should the cars in the panels be? An array of inputs? And how can I separate the inputs from one tab from the ones of another? All of this, using Razor!
My real-world scenario is a little bit more complicated, but I'll start by this so that I can try to solve the rest by myself. I'm using jQuery/jQuery UI, but I'm opened to other javascript alternatives (like Backbone, etc - I just don't know them yet). Thanks in advance!
UPDATE (1):
These are my models so far:
public class CarDealership
{
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<ManufactorOnDealership> ManufactorsOnDealership { get; set; }
}
public class Manufactor
{
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<ManufactorOnDealership> DealershipsOfManufactor { get; set; }
}
// Junction class: I believe it's needed because the list of Cars belongs to this relationship
public class ManufactorOnDealership
{
public int Id { get; set; }
public int CarDealershipId { get; set; }
public int ManufactorId { get; set; }
public virtual CarDealership CarDealership { get; set; }
public virtual Manufactor Manufactor { get; set; }
public virtual ICollection<Car> CarsOnDealership { get; set; }
}
public class Car
{
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<ManufactorOnDealership> Manufactors { get; set; }
}

Related

MVC3 View Model versus Entity Framework Model

Not sure how to explain this, but here goes...
I've built a code first data model using EF 4.3. One of classes, "Address" contains typical address data, street, city, state, etc. Other classes in the model contain instances of the "Address" class.
The problem. The data will be gathered/presented using different views, some of which will require the address fields, others that will not.
I can build different view models, each having the necessary validation attributes, and copy the data back and forth between data model and view model but that seems wrong.
What am I missing? There has to be a smarter way to do this.
Thanks for your help,
Jimmy
First read these questions and their answers:
MVC: Data Models and View Models
Why Two Classes, View Model and Domain Model?
also this article could help:
ASP.NET MVC View Model Patterns
In conclusion, I think in most scenarios it's helpful to have a chubby domain model (DM) but light weight presentation models (PM) related to it. So when we want to edit only a small chunk of that fat DM, one of our PMs will raise its hand.
Imagine this class in DM:
namespace DomainModels
{
public class Person
{
public int ID { get; set; }
public string FirstName { get; set; }
public string MiddleName { get; set; }
public string LastName { get; set; }
public DateTime? DoB { get; set; }
public MyAddressDM Address { get; set; }
public string Phone { get; set; }
public IEnumerable<MyCarModel> Cars { get; set; }
//etc.
}
}
Now imagine that in one view we need to edit only Address and Phone. A light weight PM could be like:
namesapce PresentationModels
{
public PersonAddressPhone
{
public int ID { get; set;}
public string FullName { get; set;}
public string AddressSteet { get; set; }
public string AddressCity { get; set; }
public string AddressState { get; set; }
public string AddressZipCode { get; set; }
public string Phone { get; set; }
}
}
and in another view we need to add/remove cars for a person:
namesapce PresentationModels
{
public PersonCars
{
public int ID { get; set;}
public string FullName { get; set;}
public IEnumerable<PMCar> Cars { get; set;}
}
}
Mapping between DO and PM is the golden piece of this puzzle. Be sure to take a look at AutoMapper.

MVC3 Optional Bidirectional relationship code first

What I have is something like
public class BuildingUnit
{
public int ID { get; set; }
*irrelevant stuff removed*
public virtual BuildingUnitInsurance UnitInsurance { get; set; }
}
public class BuildingUnitInsurance
{
public int ID { get; set; }
*irrelevant stuff removed*
public virtual BuildingUnit BuildingUnit { get; set; }
}
What I want to do is have the relationship from the BuildingUnit to the BuildingUnitInsurance be optional, but if it does exist, the relationship from BuildingUnitInsurance to BuildingUnit must exist. I've tried a whole bunch of things with annotations and fluent api but I haven't really gotten anywhere.
The actual business case here is having a view displaying information from the BuildingUnit class, and then on that page it is possible to click a button and pop up a modal to add insurance information. Clicking the 'add insurance' button on that modal will post the insurance information to the controller and at that point it should be saved and the relationship should be created between the BuildingUnit and the BuildingUnitInsurance. Any help with the controller code would be great too since I don't really know what I would have to do there to make those relationships happen.
You need to have a one-to-zero-or-one relationship for BuildingUnit and a one-to-one required for BuildingUnitInsurance. The code below should help you and if not read more on Configuring Relationships.
public class BuildingUnit
{
[Key]
public int ID { get; set; }
[ForeignKey("UnitInsurance")]
public virtual int? UnitInsuranceId { get; set; }
public virtual BuildingUnitInsurance UnitInsurance { get; set; }
}
public class BuildingUnitInsurance
{
[Key]
public int ID { get; set; }
[Required]
[ForeignKey("BuildingUnit")]
public virtual int BuildingUnitId { get; set; }
public virtual BuildingUnit BuildingUnit { get; set; }
}
And then in your OnModelCreating handler:
modelBuilder.Entity<BuildingUnit>.HasOptional(x => x.UnitInsurance).WithRequired();
modelBuilder.Entity<BuildingUnitInsurance>.HasRequired(x => x.BuildingUnit).WithOptional();

Entity doubts - following Contoso University Tutorial

I've been following the contoso university tutorial on Microsoft´s site and I have some doubts about how the Entity Framework is doing some stuff. Here we go...
On the beginning of the tutorial, we created three classes that will be turned into tables in my database.
I´d like to know when and how entity instantiates my classes to populate the objects.
Im using code-first approach.
Example:
The classes im using:
public class Course
{
public int CourseID { get; set; }
public string Title { get; set; }
public int Credits { get; set; }
public virtual ICollection<Enrollment> Enrollments { get; set; }
}
public class Enrollment
{
public int EnrollmentID { get; set; }
public int CourseID { get; set; }
public int StudentID { get; set; }
public decimal? Grade { get; set; }
public virtual Course Course { get; set; }
public virtual Student Student { get; set; }
}
public class Student
{
public int StudentID { get; set; }
public string LastName { get; set; }
public string FirstMidName { get; set; }
public DateTime EnrollmentDate { get; set; }
public virtual ICollection<Enrollment> Enrollments { get; set; }
}
After following the tutorial I can now list all my Students and theirs respectives Course(s), as well as their properties in enrollments lists.
When did entity instantiated my Student classes and populated it with the respective Enrollment(s) lists?
How does it know what enrollments are linked to that student?
I dont see any new constructor() ever beeing called.
This might be simple but Im kinda lost here.
Thanks
It doesn't instantiate anything ahead of time, and it doesn't have to. And there won't be anything in the table representing the virtual property as such, either.
These virtual properties are used by EF at runtime to store navigation information, and the collections can be null or contain 0 or more elements. There's no magic, it's just by design that EF "new"s up the collection when it needs to.
If you want to be explicit about it, you can create a constructor on your POCO as well and set your collection equal to a new hashtable.

ASP.NET MVC 3 and One-To-Many relationship

This is a question about Models, ASP.NET MVC 3 and relationships. I'm using the code-first approach.
Imagine this simple typical scenario of an User with its Blog Posts:
public class User
{
public virtual int UserId { get; set; }
public virtual string Nickname { get; set; }
public virtual List<Post> Posts { get; set; }
}
public class Post
{
public virtual int PostId { get; set; }
public virtual string BlogText { get; set; }
}
I made it very very simple.
Well. When I create a controller using the Controller with Read/Write actions and views using Entity Framework, the collection of Posts is not considered. It's being ignored. So, I can't get this relationship to work.
If, in place of the collection, there was a single object (public virtual string Email, for example) it works normally.
I'm asking myself and to you:
Why
How do I put references to collections in my model?
It should be a simple task, I really can't understand why it doesn't work.
Thank you.
POCO should look like below to have one-to-many relationship:
public class Post
{
public int Id { get; set; }
public string BlogText { get; set; }
public virtual User User { get; set; }
}
public class User
{
public int Id { get; set; }
public string Nickname { get; set; }
public virtual ICollection<Post> Posts { get; set; }
}

asp.net mvc 3 entity framework, passing model info in Get request of create action

I'm having trouble passing view information from my Get/Create action to my view. Here are my three model classes;
public class Competition
{
public int Id { get; set; }
public int CompetitionId { get; set; }
public string Name { get; set; }
public string Prize { get; set; }
}
public class CompetitionEntry
{
public int Id { get; set; }
public int CompetitionEntryId { get; set; }
public string Name { get; set; }
public string Email { get; set; }
public int CompetitionId { get; set; }
}
public class CompetitionEntryViewModel
{
public int Id { get; set; }
public Competition Competitions { get; set; }
public int CompetitionId { get; set; }
public string Name { get; set; }
public string Email { get; set; }
}
Here is my Get/Create action in CompetitionEntry Controller;
public ActionResult Create(int id)
{
CompetitionEntryViewModel competitionentryviewmodel = db.CompetitionEntriesView.Find(id);
return View(competitionentryviewmodel);
}
I know this doesn't work. The id parameter goes into the URL fine. How to I get access to my Competition class in th Get action? I need to be able to show the competion name on my Create Competition entry view.
Thanks in advance!
public ActionResult Create(int id)
{
var data = db.CompetitionEntriesView.Find(id);
CompetitionEntryViewModel competitionentryviewmodel = new CompetitionEntryViewModel();
competitionentryviewmodel.CompetitionName = data.Name;
return View(competitionentryviewmodel);
}
What you are trying to do is build an object graph and display it through a view model. In order to do this, you need to map your domain model(s) to your view model.
You can do the mapping yourself by writing a lot of code (re-inventing the wheel), or, you could consider using third party tools to do this for you. I recommend you use an AutoMapper as it is very simple to use imo.
The other problem is that your view model contains a domain model. This is likely to cause you a lot of headache in near future. If I were you, I would replace Competition with CompetitionViewModel.
I would also consider creating a view model for a list of competitions, i.e. CompetitionsViewModel. Look into partial views to see how you can display a list of competitions.
Good luck

Resources