2013-09-11 4 views
2

Я работаю над приложением MVC 4 и столкнулся с проблемой при попытке обновить модели в ViewModel.Обновление модели и коллекции моделей на одном представлении (MVC4)

My ViewModel (подробно описано ниже) содержит один ComplexObjectOne и List<ComplexObjectTwo>.

Мои GETActionResult успешно заселяет ViewModel из базы данных, и все правильно отображается на моем View.

Проблема возникает при попытке передать ComplexObjectOne и List<ComplexObjectTwo> к POSTActionResult.

Передано правильно ComplexObject, но все, что я пробовал, проходит мимо коллекции List<ComplexObjectTwo>.

Мой ComplexModelOne Model

public class Test 
{ 
    public int Id {get;set;} 
    public string Result {get;set;} 

    public virtual ICollection<TestResult> TestResults {get;set;} 
} 

Мой ComplexModelTwo Model

public class TestResult 
{ 
    public int Id {get;set;} 
    public string Result {get;set;} 
    public string Comment {get;set;} 

    public virtual Test Test{get;set;} 
} 

Мой ViewModel

public class TestingViewModel 
{ 
    public TestingViewModel() 
    { 
     if(TestResults == null) 
     { 
      TestResults = new List<TestResult>(); 
     } 
    } 

    public Test Test {get;set;} 
    public IEnumerable<TestResult> TestResults {get;set;} 
} 

My Edit() GETActionResult

public ActionResult Edit(int id = 0) 
    { 
     var viewModel = new TestingViewModel(); 

     Test test = testRepo.GetTestById(id); 
     var results = test.TestResults; 

     viewModel.Test = test; 
     viewModel.TestResults = results; 
     return View(viewModel); 
    } 

My Edit() POSTActionResult

[HttpPost] 
[ValidateAntiForgeryToken] 
public ActionResult Edit(TestingViewModel model) 
{ 
    // do update - left out for brevity 
} 

Мои Edit.cshtml View

@model Namespace.Models.ViewModels.TestingViewModel 

@{ 
    ViewBag.Title = "Edit"; 
} 

<h2>Edit</h2> 

@using (Html.BeginForm()) 
{ 
    @Html.AntiForgeryToken() 
    @Html.ValidationSummary(true) 


    @Html.EditorFor(model => model.Test, "TestHeader") 

    <table> 
     <tr> 
      <th>Test</th> 
      <th>Result</th> 
      <th>Comment</th> 
     </tr> 
     @Html.EditorFor(model => model.TestResults, "TestResults") 

    </table> 

    <input type="submit" value="Update"/> 
} 

В моей View я использую пару EditorTemplates для отображения полей свойств.

Любая помощь, комментарии или предложения будут высоко оценены. Я хотел бы иметь возможность выполнить обновление этих объектов на одной странице, а не на нескольких страницах, к которым я обратился в шагах Create().

Спасибо,

Patrick H.(Stpatrck)

ответ

1

Заменить:

@Html.EditorFor(model => model.TestResults, "TestResults") 

с:

@Html.EditorFor(model => model.TestResults) 

, а затем переименовать шаблон EditorTemplates/TestResults.cshtml редактор для EditorTemplates/TestResult.cshtml (обратите внимание на недостающую s) и внутри заменить типовую декларацию от:

@model IEnumerable<TestResult> 

до:

@model TestResult 

Теперь, очевидно, что это приведет к избавлению от любых for или foreach петель вы могли бы написанными в этом шаблоне редактора, потому что теперь ASP.NET MVC будет автоматически вызывать шаблон для каждого элемента коллекции.

Так, например:

@foreach (var item in Model) 
{ 
    @Html.EditorFor(x => item.SomeProperty) 
} 

станет просто:

@Html.EditorFor(x => x.SomeProperty) 

Теперь посмотрим на сгенерированный разметки и обратите внимание на разницу в названиях ваших полей ввода. Перед тем, как был:

<input type="text" name="item.SomeProperty" value="foo" /> 

и теперь у вас есть:

<input type="text" name="TestResults[0].SomeProperty" value="foo" /> 

Теперь, когда вы отправите форму к действию POST модели по умолчанию Связыватель будет в состоянии успешно связать коллекцию, потому что теперь именование соблюдается. Вы можете узнать больше об этом соглашении в following blog post.

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

+0

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

Смежные вопросы