2013-09-09 4 views
0

Я пытаюсь создать сложную ViewModel, которая имеет как страницу индекса, так и страницу создания всех примечаний компании на странице сведений о компании и хотела бы получить некоторые рекомендации относительно того, это правильно.ViewModel теряет данные в сообщении

Моя проблема заключается в том, что когда я создаю новую корпоративную заметку, она не содержит никакой информации в объекте за пределами полей EditorFor, которые я включаю в свой cshtml, - он теряет все данные в ViewModel.

У меня есть модель компании и CompanyController, и в своем действии с подробной информацией я заполняю все примечания, имеющие отношение к компании, и форму, позволяющую пользователям добавлять новую заметку.

Моя компания и модель CompanyNotes очень просто:

public class Company 
{ 
    public int CompanyID { get; set; } 
    // bunch of fields related to the company 

    public virtual ICollection<CompanyNote> CompanyNotes { get; set; } 
} 


public class CompanyNote 
{ 
    public int CompanyNoteID { get; set; } 
    public DateTime Date { get; set; } 
    public string Note { get; set; } 

    public Company Company { get; set; } 
} 

У меня есть ViewModel, который выглядит следующим образом:

public class CompanyViewModel 
{ 
    public Company Company { get; set; } 

    // List of all notes associated with this company 
    public IEnumerable<CompanyNote> CompanyNotes { get; set; } 

    // A CompanyNote object to allow me to create a new note: 
    public CompanyNote CompanyNote { get; set; } 
} 

Это моя деталь действие, которое заполнит рекорд компании, получает список связанных заметок и отображает форму для создания с новым пустым объектом:

public ActionResult Details(int id = 0) 
    { 
     var viewModel = new CompanyViewModel(); 

     viewModel.Company = db.Companies.Find(id); 

     if (viewModel.Company == null) 
     { 
      return HttpNotFound(); 
     } 

     viewModel.CompanyNotes = (from a in db.CompanyNotes 
            where a.Company.CompanyID.Equals(id) 
            select a).OrderBy(x => x.Date); 

     viewModel.CompanyNote = new CompanyNote 
      { 
       Date = System.DateTime.Now, 
       Company = viewModel.Company 
      }; 

     return View(viewModel); 
    } 

Это мое действие CreateNote в моем CompanyController. (Должен ли я разделить это в отдельный частичный вид Что бы польза?)

[HttpPost] 
    [ValidateAntiForgeryToken] 
    public ActionResult CreateNote(CompanyViewModel companyViewModel) 
    { 
     CompanyNote companyNote = companyViewModel.CompanyNote; 

     if (ModelState.IsValid) 
     { 

      db.CompanyNotes.Add(companyNote); 
      db.SaveChanges(); 
      return RedirectToAction("Index"); 
     } 

     return View(companyViewModel); 

    } 

Наконец, вот упрощенная версия detail.cshtml:

@model Project.ViewModels.CompanyViewModel 

// My company detail display is here, removed for sake of berevity 
@using (Html.BeginForm("CreateNote", "Company")) 
{ 

    @Html.EditorFor(model => model.CompanyNote.Date) 
    @Html.TextAreaFor(model => model.CompanyNote.Note}) 
    <input type="submit" value="Create" /> 
} 

Когда я отправляю, мой CreateNote action имеет companyViewModel, который в основном пуст, за исключением companyViewModel.CompanyNote.Date и companyViewModel.CompanyNote.Note, которые являются полями в моей форме - все остальные данные в ViewModel равны нулю, поэтому я не уверен, как даже включить ссылку обратно в материнскую компанию.

Я даже на правильном пути здесь?

Спасибо, Робби

ответ

6

Когда я отправляю мое CreateNote действие имеет companyViewModel, который в основном пустой, за исключением companyViewModel.CompanyNote.Date и companyViewModel.CompanyNote.Note, которые поля в моей форме - все остальные данные в ViewModel равны нулю, поэтому я не уверен, как даже включить ссылку обратно в материнскую компанию.

Это совершенно нормальное поведение. Только информация, которая включена в вашу форму в качестве полей ввода, отправляется на сервер при отправке формы, и это единственная информация, которую вы когда-либо могли надеяться, что модельное связующее может получить.

Если вам нужна коллекция CompanyNotes в действии HttpPost, просто запросите свой сервер, как и в действии GET.Это можно сделать, передав компании ИД как скрытое поле:

@Html.HiddenFor(model => model.Company.CompanyID) 

Итак идея включить только в качестве исходных полей в виде информации, которую пользователь должен каким-то изменить. Для всей другой информации, ну, вы уже имеете ее в своем бэкэнде, поэтому все, что вам нужно сделать, это нажать ее, чтобы получить ее.

В отличие от классических WebForms, в ASP.NET MVC больше нет понятия ViewState. Это гораздо ближе к апатриду HTTP-протокола.

+0

Дарин, спасибо, это имеет смысл, но затем на моем посту мне нужно снова искать компанию на основе идентификатора с компанией Company = db.Companies.Find (id), а затем добавить компанию в компанию, которая похоже на ненужный вызов базы данных? –

+0

Кроме того, является ли это общепринятым способом достижения того, что я пытаюсь сделать? Должен ли я использовать частичный вид (большинство примеров, похоже, делают это!) –

+0

Да, вы должны ударить свою базу данных, если вам нужно получить сборник заметок компании. Что касается вашего вопроса о частичных взглядах, я не совсем понимаю, что здесь связано с этим вопросом. –