.net C#MVC语法-模板lambda中的递归搜索(EditorFor)

.net C#MVC语法-模板lambda中的递归搜索(EditorFor),.net,asp.net-mvc,lambda,mvc-editor-templates,.net,Asp.net Mvc,Lambda,Mvc Editor Templates,我有一个递归模型 public class Mapping { public string Value { get; set; } public List<Mapping> ChildMappings { get; set; } } 公共类映射 { 公共字符串值{get;set;} 公共列表子映射{get;set;} } 我有一个映射类的EditorTemplate。通过EditorFor(m=>m.ChildMappings)进行的正常渲染工作正常 基于数组参数

我有一个递归模型

public class Mapping
{
    public string Value { get; set; }
    public List<Mapping> ChildMappings { get; set; }
}
公共类映射
{
公共字符串值{get;set;}
公共列表子映射{get;set;}
}
我有一个映射类的EditorTemplate。通过EditorFor(m=>m.ChildMappings)进行的正常渲染工作正常

基于数组参数(2,3),我想寻找一个特定的子节点。(例如Mapping.ChildMappings[2].ChildMappings[3])

我尝试在lambda中调用一个本地方法,这给了我一个关于索引器的错误,以及所有我在模板中不能做的事情

@Html.EditorFor(m => RecurseMappings(m.BodyMappings, indexes))

@functions{
    private Mapping RecurseMappings(List<Mapping> mappings, int[] indexes)
    {
        Mapping mapping = new Mapping();

        foreach (int index in indexes)
        {
            mapping = mappings[index];
            if (mapping.ChildMappings == null) { mapping.ChildMappings = new List<RequestMapping>(); }
            mappings = mappings[index].ChildMappings;
        }

        return mappings[mappings.Count - 1];
    }
@Html.EditorFor(m=>RecurseMappings(m.BodyMappings,index))
@功能{
私有映射递归映射(列表映射,int[]索引)
{
映射映射=新映射();
foreach(索引中的int索引)
{
映射=映射[索引];
如果(mapping.ChildMappings==null){mapping.ChildMappings=new List();}
mappings=mappings[index].ChildMappings;
}
返回映射[mappings.Count-1];
}
目前,我已经退回到一个开关上,以至少促进硬编码数量的嵌套级别,如下所示:

    string[] tokens = Model.ChildIndex.Split(',');
    int[] indexes = Array.ConvertAll<string, int>(tokens, int.Parse);

   switch (indexes.GetLength(0))
    {
        case 1:
            {
                var last = Model.BodyMappings[indexes[0]].ChildMappings.Count - 1;
@Html.EditorFor(m => m.BodyMappings[indexes[0]].ChildMappings[last])
                break;
            }

        case 2:
            {
                var last = Model.BodyMappings[indexes[0]].ChildMappings[indexes[1]].ChildMappings.Count - 1;
@Html.EditorFor(m => m.BodyMappings[indexes[0]].ChildMappings[indexes[1]].ChildMappings[last])
                break;
            }
        case 3:
            {
                var last = Model.BodyMappings[indexes[0]].ChildMappings[indexes[1]].ChildMappings[indexes[2]].ChildMappings.Count - 1;
@Html.EditorFor(m => m.BodyMappings[indexes[0]].ChildMappings[indexes[1]].ChildMappings[indexes[2]].ChildMappings[last])
                break;
            }
        case 4:
            {
                var last = Model.BodyMappings[indexes[0]].ChildMappings[indexes[1]].ChildMappings[indexes[2]].ChildMappings[indexes[3]].ChildMappings.Count - 1;
@Html.EditorFor(m => m.BodyMappings[indexes[0]].ChildMappings[indexes[1]].ChildMappings[indexes[2]].ChildMappings[indexes[3]].ChildMappings[last])
                break;
            }
        case 5:
            {
                var last = Model.BodyMappings[indexes[0]].ChildMappings[indexes[1]].ChildMappings[indexes[2]].ChildMappings[indexes[3]].ChildMappings[indexes[4]].ChildMappings.Count - 1;
@Html.EditorFor(m => m.BodyMappings[indexes[0]].ChildMappings[indexes[1]].ChildMappings[indexes[2]].ChildMappings[indexes[3]].ChildMappings[indexes[4]].ChildMappings[last])
                break;
            }
        default:
            break;
    }
string[]tokens=Model.ChildIndex.Split(',');
int[]index=Array.ConvertAll(令牌,int.Parse);
开关(index.GetLength(0))
{
案例1:
{
var last=Model.BodyMappings[索引[0]].ChildMappings.Count-1;
@EditorFor(m=>m.BodyMappings[index[0]].ChildMappings[last])
打破
}
案例2:
{
var last=Model.BodyMappings[index[0]].ChildMappings[index[1]].ChildMappings.Count-1;
@EditorFor(m=>m.BodyMappings[index[0]].ChildMappings[index[1]].ChildMappings[last])
打破
}
案例3:
{
var last=Model.BodyMappings[index[0]].ChildMappings[index[1]].ChildMappings[index[2].ChildMappings.Count-1;
@EditorFor(m=>m.BodyMappings[index[0]].ChildMappings[index[1]].ChildMappings[index[2]].ChildMappings[last])
打破
}
案例4:
{
var last=Model.BodyMappings[index[0]].ChildMappings[index[1]].ChildMappings[index[2].ChildMappings[index[3].ChildMappings.Count-1;
@Html.EditorFor(m=>m.BodyMappings[index[0]].ChildMappings[index[1]].ChildMappings[index[2].ChildMappings[index[3]].ChildMappings[last])
打破
}
案例5:
{
var last=Model.BodyMappings[index[0]].ChildMappings[index[1]].ChildMappings[index[2].ChildMappings[index[3].ChildMappings[index[4].ChildMappings.Count-1;
@Html.EditorFor(m=>m.BodyMappings[index[0]].ChildMappings[index[1]].ChildMappings[index[2].ChildMappings[index[3].ChildMappings[index[4]].ChildMappings[last])
打破
}
违约:
打破
}

那么,有没有一种方法可以像我第一次尝试失败一样将我在包中的工作打包?我也尝试了lambda代码块,但由于无法将其转换为表达式树而被拒绝。

好吧,这可能不是预期的方法,但在为要拾取的对象创建新的Html帮助程序时,它会起作用:

@{  
    var dd =  new ViewDataDictionary<Mapping>(RecurseMappings(Model.BodyMappings, indexes));
    var dc = new MyDataContainer() { ViewData = dd };
    var help = new HtmlHelper<Mapping>(ViewContext, dc);
}

@help.EditorFor(m => m)

这给了我相同的运行时错误(调试表明它甚至没有尝试输入该方法).System.InvalidOperationException未经用户代码处理Message=模板只能用于字段访问、属性访问、一维数组索引或单参数自定义索引器表达式。这感觉更接近,因为它没有中断,而是服务于多个元素(全部在层次结构中)模型绑定有点不正确。结果需要按名称绑定回顶级父级,否则不能作为父级模型的“BodyMappings”集合组件发布。
public class MyDataContainer : IViewDataContainer
{
    public ViewDataDictionary ViewData { get; set; }
}