0

I have the following view model

public class MyCVViewModel
{
    [Required]
    [StringLength(100, ErrorMessage = "Resume Title cannot exceed 100 characters.")]
    [Display(Name = "Resume Title")]
    public string ResumeTitle { get; set; }
    [Required]
    [StringLength(1000, ErrorMessage = "Personal Statment cannot exceed 1000 characters.")]
    [Display(Name = "Personal Statement")]
    public string Statement { get; set; }

    public List<MyCompanyViewModel> Companies { get; set; }
}

public class MyCompanyViewModel
{
    [Required]
    [StringLength(100, ErrorMessage = "Company Name cannot exceed 100 characters.")]
    [Display(Name = "Company Name")]
    public string CompanyName { get; set; }
    [Required]
    [StringLength(100, ErrorMessage = "Job Title cannot exceed 100 characters.")]
    [Display(Name = "Job Title")]
    public string JobTitle { get; set; }
    [Required]
    [DataType(DataType.Date)]
    [Display(Name = "Start Date")]
    public DateTime JobStartDate { get; set; }
    [Required]
    [DataType(DataType.Date)]
    [Display(Name = "End Date")]
    public DateTime JobEndDate { get; set; }
    [Required]
    [StringLength(1000, ErrorMessage = "Job Description cannot exceed 1000 characters.")]
    [Display(Name = "Job Description")]
    public string JobDescription { get; set; }
}

I have a controller which saves a list of companies to the view model:

public ActionResult Create()
{
    var model = new MyCVViewModel()
    {

    };

    model.Companies = new List<MyCompanyViewModel>();
    model.Companies.Add(new MyCompanyViewModel() { CompanyName = "Company1", JobTitle = "Gyprocker", JobDescription = "Hello" });
    model.Companies.Add(new MyCompanyViewModel() { CompanyName = "Company2", JobTitle = "Gyprocker2", JobDescription = "Hello" });
    model.Companies.Add(new MyCompanyViewModel() { CompanyName = "Company3", JobTitle = "Gyprocker3", JobDescription = "Hello" });
    model.Companies.Add(new MyCompanyViewModel() { CompanyName = "Company4", JobTitle = "Gyprocker4", JobDescription = "Hello" });

    return View("~/Views/Dashboard/CV/Create.cshtml", model);
}

Now I am not exactly sure how to post this list view model back to the database, I am using entity framework code first approach and this is what I tried:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(MyCVViewModel model)
{
    if (!ModelState.IsValid)
    {
        return View("~/Views/Dashboard/CV/Create.cshtml", model);
    }
    else
    {
        var cv = new CV();

        cv.Title = model.ResumeTitle;
        cv.Statement = model.Statement;
        cv.Id = User.Identity.GetUserId();
        cv.Companies = new List<Company>();
        foreach (var company in model.Companies)
        {
            cv.Companies.Add(company); //this line has error saying cannot convert viewmodel to entity
        }

        repository.AddCV(cv);

        return RedirectToAction("List");
    }
}

So what is the best way to add a list viewmodel to the database?

Update

foreach (var company in model.Companies)
{
    cv.Companies.Add(
            new Company
            {
                CompanyName = company.CompanyName,
                JobTitle = company.JobTitle,
                StartDate = company.JobStartDate,
                EndDate = company.JobEndDate,
                Description = company.JobDescription
            });
}

Tried this and it works, is there any other approaches?

tereško
  • 58,060
  • 25
  • 98
  • 150
Mindless
  • 2,352
  • 3
  • 27
  • 51
  • In you `foreach` loop you need to initialize a new `Company` (the data entity) and then map the properties of `MyCompanyViewModel` to `Company` –  Dec 08 '14 at 01:21
  • Do you really want to display a fixed number (4) of companies in the view? –  Dec 08 '14 at 01:30
  • @Stephen No it won't be a fixed number of 4, I will get companies from user input – Mindless Dec 08 '14 at 01:32

1 Answers1

1

In the foreach loop you need to initialize a new Company

foreach (var item in model.Companies)
{
  Company company = new Company()
  {
    CompanyName = item.CompanyName,
    JobTitle = item.JobTitle,
    // etc for other properties
  };
  cv.Companies.Add(company);
}
  • is there any other better approaches? – Mindless Dec 08 '14 at 01:34
  • 1
    You can use tools such as [automapper](https://github.com/AutoMapper/AutoMapper) to make it a bit easier - just means you have less code but its essentially doing the same thing as your code. Reason I asked about the number of companies was I just posted [this answer](http://stackoverflow.com/questions/27340434/how-to-put-two-arrays-as-key-and-values-of-each-other-in-c/27349929#27349929) on how to dynamically add an remove collection items in a view –  Dec 08 '14 at 01:37
  • That is actually what I am looking for right now, Thanks for the answer link – Mindless Dec 08 '14 at 01:38
  • 1
    @EricWang, Obviously that answer is specific to the question but should be easy enough to adapt to your needs. Just need to get the naming correct. In you case you have a property `Companies` which is the collection so the controls would be `name=Companies[i].Index` etc. –  Dec 08 '14 at 01:45
  • In my view, I encounter Object reference not set to an instance of object error, if I am not editing, then how do you still use for loop inside view because model count for companies is going to be 0 intially – Mindless Dec 08 '14 at 02:24
  • If there are no initial companies, then the loop will just be skipped. Without seeing more code its hard to tell but I'm guessing that you have not initialized `Companies` (as in `model.Companies = new List`), so `for(int i = 0; i < Model.Companies.Count; i++)` is throwing an exception, but if that's not the problem, it would be best to ask a new question with the relevant code –  Dec 08 '14 at 02:30
  • Yea I tried that but everything inside the loop isn't displayed for some reason – Mindless Dec 08 '14 at 02:39
  • Sorry, but I don't understand. If you don't add any items to the collection (i.e. you a creating a new `MyCVViewModel` with an empty list of companies) then nothing will be displayed because there is nothing to display. You really need to ask a new question showing your code so I can see where the error is. –  Dec 08 '14 at 02:45