gpt4 book ai didi

asp.net-mvc - 如何在 MVC 3 中基于 XML 文件动态创建控件

转载 作者:行者123 更新时间:2023-12-02 08:33:21 25 4
gpt4 key购买 nike

我有一个 XML 文件以 XML 格式存储在数据库中,其中包含一些控件,例如下拉文本框、标签文本区域等,这些控件可能有也可能没有初始值。所以我的目标是读取 XML 文件,并根据控件类型,我需要动态创建该控件并关联初始值(如果有),并且页面的预览必须显示在 View 中。任何人请帮助我如何在 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 的 View 模型:

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,然后是一个映射层,最终为我们提供 View 模型的实例。我将其保留在本答案的范围之外,因为您可以通过多种方式实现它(XmlSerializer、XDocument、XmlReader,...)。

我想您已经有一个 View 模型的实例。像这样:

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);
}

因此,我对一些值进行了硬编码以说明该概念,但通常,一旦实现存储库和映射层,此 Controller 操作将如下所示:

public ActionResult Index()
{
string xml = _repository.GetControls();
var model = Mapper.Map<string, MyViewModel>(xml);
return View(model);
}

好的,现在让我们转到相应的 Index.cshtml View ,其中将包含以下表单:

@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" />
}

好的,现在我们可以为我们想要处理的控件定义相应的编辑器模板:

  • ~/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)

到目前为止,一切都很好。在此阶段,您应该能够呈现包含动态控件的表单。但当然,这样的形式对任何人来说都是毫无用处的。最好的是能够发布此表单并捕获用户在 Controller 操作中输入的值,以便我们可以处理它们。

Controller 操作如下所示:

[HttpPost]
public ActionResult Index(MyViewModel model)
{
... process the values
}

现在这很好,但当然它不会工作,因为 ControlViewModel View 模型是一个抽象类,默认模型绑定(bind)器不知道要实例化哪个具体实现。因此,我们需要通过编写自定义模型绑定(bind)器来帮助他=>:

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-mvc - 如何在 MVC 3 中基于 XML 文件动态创建控件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6329461/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com