2016-10-25 3 views
0

мой взгляд, связан с этой модельюMVC ViewModel частично нулевой

public class HomepageViewModel 
{ 
    public HomepageViewModel() 
    { 
     Regions = new List<TMRegion>(); 
    } 

    public List<TMRegion> Regions { get; set; } 

    public int SelectedRegion { get; set; } 

    public SelectList SelectListRegions 
    { 
     get 
     { 
      List<SelectListItem> items = new List<SelectListItem>(); 
      foreach (var tmRegion in Regions) 
      { 
       items.Add(new SelectListItem() 
       { 
        Value = tmRegion.Value.ToString(), 
        Text = tmRegion.Display 
       }); 
      } 
      return new SelectList(items); 
     } 
    } 
} 

мой взгляд, как это -

@model ProSell.Admin.Models.ViewModels.HomepageViewModel 

@using (Html.BeginForm("Index", "Search", FormMethod.Post, new { viewModel = Model })) 
{ 
    @Html.HiddenFor(m=>m.Regions) 


    @Html.DropDownListFor(model => model.SelectedRegion, Model.SelectListRegions.Items as List<SelectListItem>, "Select a region") 

<input type="submit"/> 

}

Мой контроллер заполнит Регионы, как это -

// GET: Search 
    public async Task<ViewResult> Index(HomepageViewModel viewModel) 
    { 
     if (viewModel.Regions.Count == 0) 
     { 
      viewModel = new HomepageViewModel(); 
      JavaScriptSerializer js = new JavaScriptSerializer(); 
      viewModel.Regions = 
       js.Deserialize<TMRegion[]>(
        await _ApiConsumer.ExecuteGetMethod("myurlinhere")) 
        .ToList(); 

     } 

     return View(viewModel); 
    } 

The Dow Dow n отображается в представлении. Когда я выбираю регион и отправляю HomeViewModel, у SelectedRegion правильно установлен любой идентификатор, но коллекция Регионов пуста.

Как сохранить список в модели на отправке?

+0

Попробуйте удалить 'новый {ViewModel = Модель}', вы не должны это для данных формы для представления контроллеру. –

+2

Вы не можете привязать коллекцию сложных объектов к '' - посмотрите на html его генерацию, чтобы понять! Не отправляйте назад коллекцию - если вам это нужно (и единственный раз, когда вы делаете это, если 'ModelState' недействителен, и вам нужно вернуть представление), то получите его снова. И измените модель на «public IEnumerable SelectListRegions {get; задавать; } '- Ответственность контроллера за его заполнение, а не модель –

+1

И нет смысла бросать' SelectList' в 'List ' - вы просто должны быть '@ Html.DropDownListFor (model => model.SelectedRegion, Model.SelectListRegions, «Выбрать регион») –

ответ

1

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

Как Стивен сказал, что вы можете повторно заполнить коллекции Regions с вашего контроллера, или если вам это нужно, когда вы возвращаете представление из-за ошибки ModelState, вы можете добавить код популяции в конструктор вашей модели.

Также вы можете очистить вашу собственность коллекции, как это:

public IEnumerable<SelectListItem> SelectListRegions 
{ 
    get 
    { 
     return Regions.Select(x => new SelectListItem 
     { 
      Text = x.Display, 
      Value = x.Value.ToString() 
     }); 
    } 
} 

и в вашем Вид:

@Html.DropDownListFor(model => model.SelectedRegion, Model.SelectListRegions, "Select a region")