Я пытаюсь научить себя 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? Как я могу получить заполненное содержимое полей в действии моего контроллера, поэтому я могу устно сохранить это замечание с правильным заполненным шаблоном в базе данных? Я был бы очень благодарен за вашу помощь. Направьте меня на учебные пособия, если вы не захотите записать это, что может мне помочь. Просто дай мне несколько стартеров. Я был у него на рабочий день ...
Возможный дубликат [Рекомендации по отладке привязки ASP.NET MVC] (http: // stackoverflow.com/questions/4651085/best-practices-for-debugging-asp-net-mvc-binding) –
Хорошо, спасибо за ответ, но разве это не слишком тупо? Я уже заметил, что данные не отправлены назад, и я хотел бы знать правильный способ установки такой сложной модели в MVC. Или я чего-то не хватает? Извините, если я это сделал. –
Я обнаружил, что поведение связующего по умолчанию при выполнении того, что вы ожидаете большую часть времени, не очень хорошо документировано. В сложном случае, таком как ваш, я всегда считал наиболее поучительным переходить по стандарту связующего кода, как объясняется в ссылке, которую я опубликовал, таким образом вы получаете информацию из первых рук, почему она не является обязательными параметрами так, как вы ожидаете. Если «тупой» приписывается моей персоне, извините, что я не хотел расстраиваться. –