asp.net-mvc – 如何在MVC 3中基于XML文件动态创建控件
|
我有一个XML文件存储在数据库中作为XML格式,其中包含一些控件,如下拉文本框,标签文本区域等,可能有或没有初始值。所以我的目标是读取XML文件,并基于控件类型,我需要动态创建该控件,并关联初始值(如果有)和页面的预览必须在视图中显示。任何人都请帮助我如何在MVC 3中为这种情况下动态创建控件。 例如:我的xml文件将看起来像这样。 <?xml version="1.0" encoding="utf-8" ?>
<controls>
<control>
<type name="label">
<property name="Visible" value="true"/>
<property name="ID" value="Label1"/>
.
.
.
</type>
</control>
<control>
<type name="TextBox">
<property name="Visible" value="true"/>
<property name="ID" value="TextBox1"/>
.
.
.
</type>
</control>
.
.
.
</controls>
提前致谢。 解决方法我会尽力为你提供一些提示,可能会给你一些想法。一如既往,我们首先定义一个代表UI的视图模型: public class MyViewModel
{
public ControlViewModel[] Controls { get; set; }
}
public abstract class ControlViewModel
{
public abstract string Type { get; }
public bool Visible { get; set; }
public string Label { get; set; }
public string Name { get; set; }
}
public class TextBoxViewModel : ControlViewModel
{
public override string Type
{
get { return "textbox"; }
}
public string Value { get; set; }
}
public class CheckBoxViewModel : ControlViewModel
{
public override string Type
{
get { return "checkbox"; }
}
public bool Value { get; set; }
}
public class DropDownListViewModel : TextBoxViewModel
{
public override string Type
{
get { return "ddl"; }
}
public SelectList Values { get; set; }
}
因此,我们定义了一些我们希望在应用程序中处理的基本控件。下一步将是有一个存储库方法,将查询数据库,获取XML,然后一个映射层,最终将为我们提供一个我们的视图模型的实例。我把这个作为范围之外的这个答案,因为有很多方法可以实现它(XmlSerializer,XDocument,XmlReader,…)。 我想你已经有一个视图模型的实例。喜欢这个: public ActionResult Index()
{
var model = new MyViewModel
{
Controls = new ControlViewModel[]
{
new TextBoxViewModel
{
Visible = true,Label = "label 1",Name = "TextBox1",Value = "value of textbox"
},new CheckBoxViewModel
{
Visible = true,Label = "check label",Name = "CheckBox1",Value = true
},new DropDownListViewModel
{
Visible = true,Label = "drop label",Name = "DropDown1",Values = new SelectList(
new[]
{
new { Value = "1",Text = "text 1" },new { Value = "2",Text = "text 2" },new { Value = "3",Text = "text 3" },},"Value","Text","2"
)
}
}
};
return View(model);
}
所以我硬编码了一些值,以说明这个概念,但通常这个控制器动作看起来像这样一旦你实现了存储库和映射层: public ActionResult Index()
{
string xml = _repository.GetControls();
var model = Mapper.Map<string,MyViewModel>(xml);
return View(model);
}
OK,现在让我们移动到相应的Index.cshtml视图,它将包含以下形式: @model MyViewModel
@using (Html.BeginForm())
{
for (int i = 0; i < Model.Controls.Length; i++)
{
if (Model.Controls[i].Visible)
{
<div>
@Html.HiddenFor(x => x.Controls[i].Type)
@Html.HiddenFor(x => x.Controls[i].Name)
@Html.EditorFor(x => x.Controls[i])
</div>
}
}
<input type="submit" value="OK" />
}
OK,所以现在我们可以为我们想要处理的控件定义相应的编辑器模板: >/ Views / Shared / EditorTemplates / TextBoxViewModel.cshtml @model AppName.Models.TextBoxViewModel @Html.LabelFor(x => x.Value,Model.Label) @Html.TextBoxFor(x => x.Value) >/ Views / Shared / EditorTemplates / CheckBoxViewModel.cshtml @model AppName.Models.CheckBoxViewModel @Html.CheckBoxFor(x => x.Value) @Html.LabelFor(x => x.Value,Model.Label) >/ Views / Shared / EditorTemplates / DropDownListViewModel.cshtml @model AppName.Models.DropDownListViewModel @Html.LabelFor(x => x.Value,Model.Label) @Html.DropDownListFor(x => x.Value,Model.Values) 到现在为止还挺好。在这个阶段,你应该能够渲染一个包含动态控件的窗体。但是当然这样的形式对任何人都是没用的。什么是好的是有可能POSTing此表单和捕获用户输入的值在控制器操作,以便我们可以处理它们。 控制器操作将如下所示: [HttpPost]
public ActionResult Index(MyViewModel model)
{
... process the values
}
现在这将是很好,但是当然不会工作,因为ControlViewModel视图模型是一个抽象类,并且默认模型绑定器没有关于哪个具体实现实例化的线索。所以我们需要帮助他=>通过编写自定义模型绑定器: public class ControlModelBinder : DefaultModelBinder
{
protected override object CreateModel(ControllerContext controllerContext,ModelBindingContext bindingContext,Type modelType)
{
var type = bindingContext.ValueProvider.GetValue(bindingContext.ModelName + ".Type");
object model = null;
switch (type.AttemptedValue)
{
case "textbox":
{
model = new TextBoxViewModel();
break;
}
case "checkbox":
{
model = new CheckBoxViewModel();
break;
}
case "ddl":
{
model = new DropDownListViewModel();
break;
}
default:
{
throw new NotImplementedException();
}
};
bindingContext.ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => model,model.GetType());
return model;
}
}
它将在Application_Start中注册并关联到ControlViewModel类型): ModelBinders.Binders.Add(typeof(ControlViewModel),new ControlModelBinder()); (编辑:安卓应用网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- asp.net – Orchard CMS高级主题
- 如何在ASP.NET项目中正确引用JavaScript文件?
- 我可以使用ASP.NET成员身份实体框架吗?
- ASP.NET MVC4 Razor模板简易分页效果
- asp.net – 只能将一个ScriptManager实例添加到页面中
- asp.net – gridview在viewstate中保存数据吗?
- asp.net – ASP.MVC CORE网站的最大上传大小
- asp.net – SQL Server查询从ADO.NET运行速度比SSMS慢
- asp.net – 将包含子集合的DTO映射回域模型的设计模式
- asp.net-mvc – ASP.NET MVC的一个路由,两个不同的视图
- asp.net-mvc – Visual Studio提示使用Razor语法
- asp.net-mvc – 使用Castle Windsor在ASP.NET MV
- 用于Asp.Net应用程序的SSO的最佳方法,从具有多个
- asp.net-mvc-4 – 创建和编辑MVC4的相同视图
- asp.net-mvc-3 – 如何模拟查询字符串
- asp.net-mvc – 在RedirectToRoute和RedirectToA
- asp.net – 如何自动执行功能/集成测试和数据库回
- asp.net-mvc – 如何将KendoUI DropDownListFor绑
- asp.net-mvc – DisplayFor和ValueFor之间的区别
- asp.net-mvc-3 – MVC 3子域路由
