Tony, I have been searching for the same thing also. You are right, there is a TreeView for ASP.NET Core, but it's for Windows Forms and not web pages:
Microsoft Docs TreeView Class
I have also looked at Telerik and Syncfusion, but am trying to avoid paying for a solution.
First, for the data structure, I did find a NuGet package called TreeCollections written by David West here:
https://github.com/davidwest/TreeCollections
I have implemented that and can successfully build one or multiple hierarchical trees from my data. You might want to look at that for your tree data structure.
Now to display the data on a web page, I don't think Microsoft has any tools to help us. I have searched like you have. You mention JsTree, and I think that is a viable option, but it's not html-only as you specified. I think we will have to use at least some javascript.
There are two good lazy-load implementations of JSTree on SO here: Lazy-loading TreeView with JsTree in Asp.Net MVC
Depending on the size and depth of your tree, if you can pull your data dynamically as the user navigates the tree, this might be the best solution. If you want to pre-load your data into a tree structure first, like I am doing with TreeCollections, then perhaps populating a structure will work, but it will still need help with javascript if you want to interactively show/hide branches on the tree.
Update: I was able to load and display a hierarchical tree on my web page with very little code, using jsTree. I found I didn't need TreeCollections at all. First, the model that holds each node's data:
public class JsTreeModel
{
public string id { get; set; }
public string parent { get; set; }
public string text { get; set; }
public string icon { get; set; }
public string state { get; set; }
public bool opened { get; set; }
public bool disabled { get; set; }
public bool selected { get; set; }
public string li_attr { get; set; }
public string a_attr { get; set; }
}
Here's my code that loads the data into a List. I am working in ASP.Net Core 3.1, so I use System.Text.Json to serialize the data. First retrieve your data from the db into a List<> of items, no sorting is required. Then:
using System.Text.Json;
[...]
IList<JsTreeModel> nodes = new List<JsTreeModel>();
foreach (var item in items)
{
nodes.Add(new JsTreeModel
{
id = item.Id.ToString(),
parent = item.ParentId == null ? "#" : item.ParentId.ToString(),
text = item.Name
});
}
//Serialize to JSON string.
ViewBag.Json = JsonSerializer.Serialize(nodes);
return View();
Then in your view, you simply need one div that holds the tree:
<div id="jstree"></div>
and this javascript that will populate it:
<script type="text/javascript">
$(document).ready(function () {
$('#jstree').jstree({
"core" : {
"data" : @Html.Raw(ViewBag.Json)
}
});
});
</script>
jsTree will go through the Json data and create a ul structure from it and put that into the div. Very easy!