I have a recursive model.
public class Mapping
{
public string Value { get; set; }
public List<Mapping> ChildMappings { get; set; }
}
I have an EditorTemplate for the Mapping class. Normal rendering via EditorFor( m => m.ChildMappings) works fine.
Based on an array parameter (2,3), I'd like to seek a specific descendant node. (Mapping.ChildMappings[2].ChildMappings[3] for example).
I've tried calling a local method within the lambda, which gave me an error about indexers and all the things I can't do in a template.
@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];
}
For the moment I've fallen back on a switch to at least facilitate a hard coded number of nested levels, like this:
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;
}
So, Is there a way to wrap up what I have working in a package more like my failed first attempt? I've also tried a lambda code block, only to be denied because it can't be converted to an expression tree.
Well, probably this is not the intended way, but it works when you create a new Html-Helper for the object you want to pick:
@{
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)
In a source file the definition of a custom data container, since I could not find a class that implements the interface.
public class MyDataContainer : IViewDataContainer
{
public ViewDataDictionary ViewData { get; set; }
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.