2016-03-11 2 views
-1

У меня есть одна модель и два ViewModelsИспользование ViewModel размещать в модели

Модель:

public class WebPages 
{ 
    [Key] 
    public int WebPagesId { get; set; } 
    public String DomainName { get; set; } 
    public DateTime DomainStart { get; set; } 
    public DateTime DomainExp { get; set; } 
} 

ViewModel:

public class WebPagesViewModel 
{ 
    public String DomainName { get; set; } 
    public DateTime DomainStart { get; set; } 
    public List<SelectListItem> DurationDays { set; get; } 
    public int SelectedDurationDays { set; get; } 
} 

Так контроллер для них:

//Get controller 

public ActionResult Create(WebPages model) 
    { 

     var vm = new WebPagesViewModel 
     { 
      DurationDays = new List<SelectListItem>() 

      { 
       new SelectListItem {Value = "1", Text = "1 año"}, 
       new SelectListItem {Value = "2", Text = "2 años"} 
       }}; 
        retrun View(vm); 
} 

//Post controller 
public async Task<ActionResult> Create(WebPagesViewModel model) 
    { 
    var endDate = DateTime.Now.AddYears(model.SelectedDurationDays); 
     var webnew = new WebPages 
     { 
      DomainName = model.DomainName, 
      DomainStart = model.DomainStart, 
      DomainExp = endDate 
     }; 
    db.WebPagesList.Add(webnew); 
     db.SaveChanges(); 
     return View(model); 

ЭТО РАБОТАЕТ ОК, Я НЕ ЛЮБЛЮ ПРОБЛЕМ MS, ЧТО Я ХОЧУ ДЕЛАТЬ, ДОБАВЛЯЕТ НОВЫЕ ДНИ К существующей DomainExp конкретной DomainName моей базе данных.

Я пытаюсь сделать это, создавая еще один ViewModel и создать вид, как эти:

public class RenewalViewModel 
{ 

    public int SelectedDurationDays { set; get; } 
    public List<SelectListItem> AddTime { get; set; } 
    public int SelectedWebPage { get; set; } 
    public IEnumerable<SelectListItem> Webpage { get; set; } 
} 
} 

Контроллеры:

[HttpGet] 
    public async Task<ActionResult> Renewal() 
    { 
     var vm = new RenewalViewModel 
     { 
      AddTime = new List<SelectListItem> 

      { 
       new SelectListItem {Value = "1", Text = "1 año"}, 
       new SelectListItem {Value = "2", Text = "2 años"}, 
       new SelectListItem {Value = "3", Text = "3 años"}, 
       new SelectListItem {Value = "4", Text = "4 años"}, 
       new SelectListItem {Value = "5", Text = "5 años"}, 
       new SelectListItem {Value = "6", Text = "6 años"}, 
       new SelectListItem {Value = "7", Text = "7 años"}, 
       new SelectListItem {Value = "8", Text = "8 años"}, 
       new SelectListItem {Value = "9", Text = "9 años"} 
      }, 
      Webpage = new SelectList(db.WebPagesList,"WebPagesId", "DomainName") 
     }; 
     return View(vm); 

    } 

    [HttpPost] 
    public async Task<ActionResult> Renewal(RenewalViewModel vm) 
    { 

     var addDays = DateTime.Now.AddYears(vm.SelectedDurationDays); 

     var webpage = new WebPages 
     { 
      DomainExp = addDays 
     }; 
     db.Entry(webpage).State = EntityState.Modified; 

     return View(webpage); 
    } 

Но в return View(webpage); у меня этот вопрос

ххх модели .Webpages не присваивается типу модели xxx.Models.ViewModel.RenewalViewModel

Я знаю, что это потому, что я назвал, на мой взгляд RenewalViewmodel, а не веб-страниц, я хочу знать, что мой неверный шаг, чтобы сделать это, я хочу

+0

Модель в представлении '@model RenewalViewModel', поэтому вам нужно вернуть' RenewalViewModel', а не модель WebPages', то есть 'return View (vm);' –

+0

, но в этом случае, как я могу сравнить 'Дом ainExp = addDays', если 'DomainExp' находится в' WebPages' модели – Eduard

+0

Извините, я не понимаю ваш комментарий - нет, где в методах 'Renewal' или связанной модели представления есть какая-либо ссылка на любые существующие' WebPages' - все, что вы это создание и сохранение новых «веб-страниц». –

ответ

0

ошибка происходит потому, что ваше мнение имеет @model RenewalViewModel но вам передается экземпляр WebPages. Для устранения ошибки необходимо изменить оператор возврата к

return View(vm); 

Однако это будет просто привести к большему количеству ошибок, потому что ваши коллекции для обоих List<SelectListItem> свойств являются null. Если вы хотите вернуть представление, чтобы сделать больше выбора, правильным подходом является перенаправление обратно на метод GET (т. Е. Шаблон PRG). Если вам нужно вернуть представление, потому что ModelState недействителен, вам необходимо повторно назначить значения свойств AddTime и Webpage.

Сказав это, код в методе POST не имеет смысла. Все, что вы делаете, это создать новый экземпляр Webpages и сохранить его. Если вы хотите добавить дни к выбранному Webpages, вам необходимо получить его снова из базы данных, обновить и сохранить.Код должен быть

[HttpPost] 
public async Task<ActionResult> Renewal(RenewalViewModel vm) 
{ 
    if (!ModelSTate.IsValid) 
    { 
     // Populate the SelectList's 
     model.Webpage = .... 
     model.AddTime = .... 
     return View(vm); 
    } 
    // Get the data model 
    WebPages model = db.WebPagesList.Where(x => x.WebPagesId == vm.SelectedWebPage).FirstOrDefault(); 
    if (model != null) 
    { 
     // Not really sure if you mean AddYears or AddDays? 
     model.DomainExp = model.DomainExp.AddYears(vm.SelectedDurationDays); 
     db.Entry(model).State = EntityState.Modified; 
     db.SaveChanges(); 
    } 
    // Redirect 
    return RedirectToAction(....); 
} 

Side Примечание: Вместо того, чтобы повторять код как GET и методы POST, создать отдельный метод

private void ConfigureRenewalViewModel(RenewalViewModel model) 
{ 
    model.Webpage = .... 
    model.AddTime = .... 
} 

, а затем вызвать его в обоих методах до возвращения зрения

ConfigureRenewalViewModel(vm); 
return View(vm); 
+0

Я вижу, что вы приняли, а затем неприняли. Есть ли что-то, что вы не понимаете? –

+0

Отлично, можете ли вы посоветовать мне что-нибудь прочитать для создания отдельных методов? Я предположил, что я использую 'private void ...' в контроллере и 'model.Webpages' равен' DomainName' модели веб-страниц – Eduard

+0

'private void ConfigureRenewalViewModel (модель RenewalViewModel)' идет в контроллер и просто означает, что вместо того, чтобы дублируйте код для создания списков выбора как в GET, так и в POST (если вам нужно вернуть представление) - его просто в одном месте - то есть DRY. Но я не понимаю, что вы подразумеваете под _'model.Webpages' равно «DomainName» веб-страниц model_ –

0

Вы возвращенная модель, а не в ViewModel. Модель предназначена для настойчивости, а ViewModel - для вашего пользовательского интерфейса. Если вам нужен вывод операции для пользовательского интерфейса, вам нужно добавить его как свойство в ViewModel.

Изменить

return View(webpage); 

To:

return View(vm); 

Или, если вы не хотите, чтобы вернуть виртуальную машину:

return new HttpStatusCodeResult(HttpStatusCode.OK); 
Смежные вопросы