ASP.NET MVC 3复杂模型绑定问题
本文关键字:模型 绑定 问题 复杂 NET MVC ASP | 更新日期: 2023-09-27 18:03:00
我正在尝试自学MVC。我模拟了一个虚拟项目来反映我目前遇到的一个实际问题。
我的模型(s):
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 };
}
}
}
你在上面的模型中看到的是一个备注模型,代表你可以保存对一个人的评论,比如:"这个人用一个大大的微笑隐藏问题。小心那个!"您还可以看到一个备注templatemodel,以满足终端用户的一个稍微复杂的愿望,即填写某些信息(如调查)。这个'备注模型'可以有模板'Testtemplate A'。模板由字段(备注templatefieldmodel)组成,可能看起来像:'Testtemplate A'由字段组成:'字段'A', '字段'B'和'字段'C'(当然一些'Testtemplate B'可以由字段'D', 'E', 'F', 'G'组成)。我希望我讲得很清楚。如果不清楚,请问一下。最后一个模型是备注模型(后面的"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',我创建了一个备注模型,并在我的强类型视图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)
}
我们将看到第二个局部视图。因为首先我尝试了这个没有部分视图"remark templatefield"和只有2个参数(remark +模板)在POST动作"索引"。我的问题是'template'参数的'fields'属性仍然是'null'。我也注意到没有什么是真正发布的模板,直到我使用一个'EditorFor'的名称属性的模板。然而,'remark'参数在它的TemplateID属性中包含了正确的模板ID,所以我想如果我至少可以获得字段,模板并不重要。这就是我添加第二个局部视图的时候:
@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到索引的动作一直返回一个空的"模板"(好吧,模板的"名称"是填充的,因为我使它成为一个编辑器,这不是一个选项在真正的网站)和"字段"列表是空的。正如你所看到的,我再次将Content上的Textbox改为EditorFor。但是,唉,没有魔法。
所以我的问题是我亲爱的专家,如何得到一个更复杂的模型,像这样的绑定在MVC正确?我怎样才能在我的控制器的动作中得到字段的填充内容,这样我就可以最终将带有正确填充模板的注释持久化到数据库?我将非常感激你的帮助。如果你不想把它拼出来,就告诉我教程,这对我有帮助。给我来点开胃菜。我已经做了一个工作日了……
我认为您正在寻找的是集合的绑定。这可能有帮助:http://www.hanselman.com/blog/ASPNETWireFormatForModelBindingToArraysListsCollectionsDictionaries.aspx