【发布时间】:2013-03-10 18:18:40
【问题描述】:
我正在尝试自学 MVC。我模拟了一个虚拟项目来反映我目前遇到的一个实际问题。
我的模特:
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”由以下字段组成:“Field '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();
}
}
}
正如您在无参数“索引”中看到的那样,我创建了一个 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”的情况下尝试了此操作,并且在 POST 操作“索引”中只有 2 个参数(备注 + 模板)。我的问题是“模板”参数的“字段”属性仍然是“空”。我还注意到,在我使用“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 to the Index 操作不断返回一个空的“模板”(模板的“名称”已填写,因为我将其设置为 EditorFor,这在真实网站上不是一个选项)并且“字段”列表为空.如您所见,我再次将内容上的文本框更改为 EditorFor。但可惜,没有魔法。
所以我的问题是我亲爱的专家,如何在 MVC 中正确绑定像这样的更复杂的模型?如何在我的控制器的操作中获取字段的填充内容,以便最终将具有正确填充模板的备注保存到数据库中?我将非常感谢您的帮助。给我指点教程,如果你不想把它拼出来,这可以帮助我。给我一些开场白。我已经工作了一个工作日...
【问题讨论】:
-
嗯,谢谢你的回复,不过这样是不是有点太直白了?我已经观察到数据没有回发,我想知道在 MVC 中设置这样的复杂模型的正确方法。还是我错过了什么?对不起,如果我这样做了。
-
我发现默认的活页夹行为在大多数情况下都在做你期望的事情,没有很好的记录。在像您这样的复杂情况下,我总是发现逐步执行默认活页夹代码是最有启发性的,正如我发布的链接中所解释的那样,通过这种方式您可以获得第一手信息,为什么它不像您期望的那样绑定参数。如果“直率”被归咎于我的性格,我很抱歉我不是故意不高兴的。
-
不,完全不属于你的角色。英语不是我的第一语言,所以也许我犯了一个错误。我的意思是,另一个主题是关于调试的。我的问题更多是关于如何从部分视图绑定列表或模型的示例。如此“直截了当”,这个结论是不是太快了。但是……不用担心。我在您发布的主题中找到了有关绑定列表的教程。所以我会试试。您必须了解我可以查看调试器,但仍然不明白我所看到的。因为我是桌面开发人员,所以我发现 Web 开发非常困难。
-
@Zespri:您提供了最初的信息来帮助解决我的问题,但自从您发表评论以来,我无法将您作为答案。所以...有了这个评论,我想再次感谢您提供的信息。
标签: c# asp.net-mvc asp.net-mvc-3