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正确?我怎样才能在我的控制器的动作中得到字段的填充内容,这样我就可以最终将带有正确填充模板的注释持久化到数据库?我将非常感激你的帮助。如果你不想把它拼出来,就告诉我教程,这对我有帮助。给我来点开胃菜。我已经做了一个工作日了……

ASP.NET MVC 3复杂模型绑定问题

我认为您正在寻找的是集合的绑定。这可能有帮助:http://www.hanselman.com/blog/ASPNETWireFormatForModelBindingToArraysListsCollectionsDictionaries.aspx