c# – Asp.Net MVC 3动态属性的编辑器

前端之家收集整理的这篇文章主要介绍了c# – Asp.Net MVC 3动态属性的编辑器前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我们一直在试图让Editor-Template与动态属性一起使用 – 无济于事.也许你们中的一个可以帮助我们.

这是大致我们的课:

public class Criterion
{
    ...
    public string Text { get; set; }
    public dynamic Value { get; set; }
    public Type Type { get; set; }
    ...
}

我们的剃须刀视图包含一个包含部分列表的模型,每个部分都包含其中的条件列表. (我们在运行时获得这些信息.)所有这些标准应显示在编辑模式 – 关于他们的实际类型:(摘录)

@for (int i = 0; i < model.Sections.Count(); i++)
{
    for (int j = 0; j < model.Sections[i].Criteria.Count(); j++)
    {
        var criterion = model.Sections[i].Criteria[j];
        var type = criterion.Type.Name;
        var name = "Sections[" + i + "].Criteria[" + j + "].Value";
        var criterionDisplayName = criterion.Text;
        <label for="Sections_@(i)__Criteria_@(j)__Value">@criterionDisplayName</label>
        @Html.Editor(name,type)
    }
}

这样会正确显示一个复选框,但是它不会使用该值来正确设置复选框状态(如果criteria.Value为true则检查).对于其他类型,像ints一样.
(它在POST请求之后正确填写表单,但这是因为MVC使用临时模型来重新创建用户输入.)

尽可能多地尝试和研究:甚至可以使用类型为动态的属性的编辑器模板?如果是 – 我们该如何使它工作? (我们不想根据可能的类型来辨别,我们想让MVC框架根据实际的类型使用正确的编辑器模板.)

解决方法

动态不适合ASP.NET MVC的帐单.他们提醒我关于ViewBag,我讨厌ViewBag从我身体的深层织物.所以我会采取不同的方法.

我们举个例子来看看下面的模型:

public class Criterion
{
    public string Text { get; set; }
    public object Value { get; set; }
}

值可以是您希望处理的任何类型.

现在你可以有一个控制器来填充这个模型:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        var model = new[]
        {
            new Criterion { Text = "some integer",Value = 2 },new Criterion { Text = "some boolean",Value = true },new Criterion { Text = "some string",Value = "foo" },};
        return View(model);
    }
}

然后对应的视图:

@model IList<Criterion>

@using (Html.BeginForm())
{
    for (int i = 0; i < Model.Count; i++)
    {
        <div>
            @Html.LabelFor(x => x[i],Model[i].Text)
            @Html.EditorFor(x => x[i].Value,"Criterion_" + Model[i].Value.GetType().Name)
        </div>
    }

    <button type="submit">OK</button>
}

现在,对于要处理的每个类型,您可以定义相应的编辑器模板:

〜/查看/共享/ EditorTemplates / Criterion_String.cshtml:

@model string
@Html.TextBoxFor(x => x)

〜/查看/共享/ EditorTemplates / Criterion_Boolean.cshtml:

@model bool
@Html.CheckBoxFor(x => x)

〜/查看/共享/ EditorTemplates / Criterion_Int32.cshtml:

@model int
@{
    var items = Enumerable
        .Range(1,5)
        .Select(x => new SelectListItem 
        { 
            Value = x.ToString(),Text = "item " + x 
        });
}

@Html.DropDownListFor(x => x,new SelectList(items,"Value","Text",Model))

显然在这个视图中显示这个模型只是第一步.我想,您将要获取用户在POST控制器操作中输入的值以进行某些处理.在这种情况下,需要进行一些小的修改.我们需要添加一个自定义模型绑定器,该绑定器将能够在运行时实例化正确的类型,并将每个行的具体类型作为隐藏字段.我已经在this post显示了一个例子.另外请注意,在这个例子中,我使用了一个基类,而不是直接使用对象类型.

猜你在找的C#相关文章