2013-03-08 4 views
1

Я пытаюсь научить себя MVC. Я издевался над фиктивным проектом, чтобы отразить реальную проблему, которая у меня есть на данный момент.Проблема с сложной моделью ASP.NET MVC 3

Моя модель (ы):

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Web; 

namespace MvcPersistPartialView.Models { 
    public class RemarkModels { 

     public static List<RemarkTemplateModel> GetTemplateAll() { 
      return new List<RemarkTemplateModel>() {RemarkTemplateModel.Create(1), 
       RemarkTemplateModel.Create(2), 
       RemarkTemplateModel.Create(3)}; 
     } 

    } 

    public class RemarkModel { 
     public int ID { get; set; } 
     public string Content { get; set; } 
     public int TemplateID { get; set; } 
     public List<RemarkTemplateModel> Templates { get; set; } 

     public static RemarkModel Create() { 
      return new RemarkModel() { 
       Content = "This is a dummy remark, to learn MVC.", 
       TemplateID = 1, 
       Templates = RemarkModels.GetTemplateAll() 
      }; 
     } 
    } 

    public class RemarkTemplateModel { 
     public int ID { get; set; } 
     public string Name { get; set; } 
     public List<RemarkTemplateFieldModel> Fields { get; set; } 

     public static RemarkTemplateModel Create(int id) { 
      return new RemarkTemplateModel() { 
       ID = id, 
       Name = id.ToString(), 
       Fields = new List<RemarkTemplateFieldModel>() {RemarkTemplateFieldModel.Create("Label A" + id.ToString(), 
        id.ToString() + "..."), 
      RemarkTemplateFieldModel.Create("Label B" + id.ToString(), 
        id.ToString() + "..."), 
      RemarkTemplateFieldModel.Create("Label C" + id.ToString(), 
        id.ToString() + "...")} 
      }; 
     } 
    } 

    public class RemarkTemplateFieldModel { 
     public string Label { get; set; } 
     public string Content { get; set; } 

     public static RemarkTemplateFieldModel Create(string label, string content) { 
      return new RemarkTemplateFieldModel() { Label = label, 
       Content = content }; 
     } 
    } 
} 

То, что вы видите в этих моделях является RemarkModel, представляющий собой реплику, вы можете сохранить на человеке, как: «. Этот человек скрывает проблемы с большой улыбкой Часы для этого! ». Вы также видите RemarkTemplateModel, чтобы приспособить немного сложное желание моих конечных пользователей заполнить определенные фрагменты информации, например, с помощью опросов. Итак, этот «RemarkModel» может иметь шаблон «Testtemplate A». Шаблоны состоят из полей (RemarkTemplateFieldModel), которые могут выглядеть так: «Testtemplate A» состоит из полей: «Поле« A », поле« B »и поле« C »(в то время как, конечно,« Testtemplate B »может состоять из поля 'D', 'E', 'F', 'G'). Надеюсь, я сделал это ясно. Пожалуйста, спросите, не ясно ли это. Последняя модель RemarkModels ('s' сзади), это просто для быстрого извлечения всех шаблонов.

Мой контроллер:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Web; 
using System.Web.Mvc; 

namespace MvcPersistPartialView.Controllers { 
    public class HomeController : Controller { 
     public ActionResult Index() { 
      ViewBag.Message = "Welcome to ASP.NET MVC!"; 

      Models.RemarkModel r = Models.RemarkModel.Create(); 

      return View(r); 
     } 

     [HttpPost] 
     public ActionResult Index(Models.RemarkModel remark, Models.RemarkTemplateModel template, List<Models.RemarkTemplateFieldModel> fields) { 

      if (ModelState.IsValid) { 
       //Persist to database. 
      } 

      ViewBag.Message = "Welcome to ASP.NET MVC!"; 

      Models.RemarkModel r = Models.RemarkModel.Create(); 

      return View(r); 
     } 

     [AcceptVerbs("POST")] 
     public ActionResult TemplateChosen(string selectedTemplateID) { 

      Models.RemarkTemplateModel selectedTemp = (from temp in Models.RemarkModels.GetTemplateAll() 
                   where temp.ID == Convert.ToInt32(selectedTemplateID) 
                   select temp).FirstOrDefault(); 

      return PartialView("RemarkTemplate", selectedTemp); 

     } 

     public ActionResult About() { 
      return View(); 
     } 
    } 
} 

Как вы можете видеть «Index» без параметров создать RemarkModel и передать его в моем сильно типизированных Index.cshtml. Этот вид выглядит так:

@model MvcPersistPartialView.Models.RemarkModel 

@using (Html.BeginForm()) { 
    <fieldset> 
     <div class="editor-label"> 
      @Html.LabelFor(model => model.Content) 
     </div> 
     <div class="editor-field"> 
      @Html.EditorFor(model => model.Content) 
      @Html.ValidationMessageFor(model => model.Content) 
     </div> 
     <div class="editor-label"> 
      @Html.LabelFor(model => model.Templates) 
     </div> 
     <div class="editor-field"> 
      @Html.DropDownListFor(
      m => m.TemplateID, 
      new SelectList(Model.Templates, "ID", "Name"), 
      new { 
       id = "templateDdl", 
       data_url = Url.Action("TemplateChosen", "Home") 
      } 
     ) 
      <input type="button" value="Change template" id="template-button" /> 
     </div> 
     <div id="template"> 
      @Html.Partial("RemarkTemplate", Model.Templates.First()) 
     </div> 
     <p> 
      <input type="submit" value="Create" /> 
     </p> 
    </fieldset> 
} 

Пока все хорошо. Я уже здесь, чтобы обратиться за помощью к DropDownListFor, теперь это работает как шарм (так что спасибо сообществу). Мы дошли до сути моего вопроса, благодарю вас за терпение. Частичный вид «RemarkTemplate» выглядит так:

@model MvcPersistPartialView.Models.RemarkTemplateModel 
<div class="display-field"> 
    @Html.Encode(Model.ID) 
</div> 
<div class="display-field"> 
    @* @Html.Encode(Model.Name)*@ 
    @Html.EditorFor(m => m.Name) 
</div> 
@foreach (MvcPersistPartialView.Models.RemarkTemplateFieldModel field in Model.Fields) { 
@* <div class="editor-label"> 
     @Html.Encode(field.Label) 
    </div> 
    <div class="editor-field"> 
     @Html.TextBox("Content", field.Content) 
    </div>*@ 
    @Html.Partial("RemarkTemplateField", field) 
} 

Мы доберемся до второго частичного вида. Потому что сначала я пробовал это без частичного представления «RemarkTemplateField» и только 2 параметра (примечание + шаблон) в «Указателе POST». Моя проблема в том, что свойство 'fields' параметра 'template' оставалось «null». Я также заметил, что ничего не было опубликовано о шаблоне, пока я не использовал «EditorFor» для свойства имени шаблона. Параметр «примечание», однако, содержал правильный идентификатор шаблона в свойстве TemplateID, поэтому я решил, что, если я могу получить поля, шаблон не имеет значения. Так вот, когда я добавил второй частичный вид:

@model MvcPersistPartialView.Models.RemarkTemplateFieldModel 
<div class="editor-label"> 
    @Html.Encode(Model.Label) 
</div> 
<div class="editor-field"> 
    @*@Html.TextBox("Content", Model.Content)*@ 
    @Html.EditorFor(m => m.Content) 
</div> 

Это все отлично. Очень хорошо. Но действие POSTback to the Index продолжает возвращать пустой «шаблон» (ну, «имя» шаблона заполняется, поскольку я сделал его редактором, который не является вариантом на реальном сайте), а список «поля» пуст , Как вы можете видеть, я снова сменил текстовое поле на контенте на редактор. Но, увы, нет волшебства.

Итак, мой вопрос - мои дорогие эксперты, как получить более сложную модель, подобную этой, связанной в MVC? Как я могу получить заполненное содержимое полей в действии моего контроллера, поэтому я могу устно сохранить это замечание с правильным заполненным шаблоном в базе данных? Я был бы очень благодарен за вашу помощь. Направьте меня на учебные пособия, если вы не захотите записать это, что может мне помочь. Просто дай мне несколько стартеров. Я был у него на рабочий день ...

+0

Возможный дубликат [Рекомендации по отладке привязки ASP.NET MVC] (http: // stackoverflow.com/questions/4651085/best-practices-for-debugging-asp-net-mvc-binding) –

+0

Хорошо, спасибо за ответ, но разве это не слишком тупо? Я уже заметил, что данные не отправлены назад, и я хотел бы знать правильный способ установки такой сложной модели в MVC. Или я чего-то не хватает? Извините, если я это сделал. –

+0

Я обнаружил, что поведение связующего по умолчанию при выполнении того, что вы ожидаете большую часть времени, не очень хорошо документировано. В сложном случае, таком как ваш, я всегда считал наиболее поучительным переходить по стандарту связующего кода, как объясняется в ссылке, которую я опубликовал, таким образом вы получаете информацию из первых рук, почему она не является обязательными параметрами так, как вы ожидаете. Если «тупой» приписывается моей персоне, извините, что я не хотел расстраиваться. –

ответ

0

Я думаю, что вы ищете связывание коллекций. Это может помочь: http://www.hanselman.com/blog/ASPNETWireFormatForModelBindingToArraysListsCollectionsDictionaries.aspx

+0

Большое спасибо за ответ. Да, это связано с тем, как связать список. Я использовал этот url, чтобы понять это: [link] (http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx). Кроме того, я не понял, что вы можете поместить все сущности из частичных представлений в свои действия слишком долго, так как типы одинаковы. Итак, я получил всю сложную модель для работы. Дело закрыто. О, p.s .: Я также должен был найти помощников HiddenFor для получения идентификаторов и других неизменяемых значений контроллеру. –

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