I want to use treeview to display Campus/Building/Floor/Room data structure in razor page. I am having a problem to bind the data. I want to use UrlAdaptor
I have created classes as follows:
public class Campus
{
//public int Id;
public string Code;
public string Name;
public bool Expanded;
public bool Selected;
//public bool HasChild;
public List<Buildings> Child;
}
public class Buildings
{
//public int ParentId;
//public int Id;
public string Code;
public string Name;
public bool Expanded;
public bool Selected;
//public bool HasChild;
public List<Floors> Child;
}
public class Floors
{
//public int ParentId;
//public int Id;
public string Code;
public string Name;
public bool Expanded;
public bool Selected;
//public bool HasChild;
public List<Rooms> Child;
}
public class Rooms
{
//public int ParentId;
//public int Id;
public string Code;
public string Name;
public bool Expanded;
public bool Selected;
//public bool HasChild;
}
I have a method GetLocations() with return type List<Campus> which returns hierarchy as shown using classes above:
Campus-1
Building-1
Floor-1
Room-1
Room-2
Room-3
...
Floor-2
Room-1
...
Building-2
Floor-1
Room-1
...
Campus-2
....
On razor view I have treeview control:
<ejs-treeview id="listdata" loadOnDemand="false" showCheckBox="true" >
<e-treeview-fields id="Code" text="Name" hasChildren="Code" expanded="true">
<e-data-manager url="/Cora/Create?handler=GetLocations" adaptor="UrlAdaptor" crossDomain="true">
</e-data-manager>
</e-treeview-fields>
</ejs-treeview>
Can you please provide example how to set datasource/bind data and treeview fields properties properly on razor page.
Hi Mensud,
Greetings from Syncfusion support.
From your shared details, we understand that you want to TreeView component with the UrlAdaptor. Based on your need, we have prepared an Asp.Net Core sample by rendering TreeView with UrlAdaptor. Here, we have fetched the datas from the database and return the items in JSON format to bind for TreeView.
Check out the below code snippets and sample for further assistance.
|
[Index.cshtml] <ejs-treeview id="tree"> <e-treeview-fields id="Id" text="Name" parentID="ParentId" hasChildren="HasTeam" expanded="IsExpanded" > <e-data-manager url="/TreeView/UrlDataSource" adaptor="UrlAdaptor" ></e-data-manager> </e-treeview-fields> </ejs-treeview>
[TreeViewController.cs] public ActionResult UrlDatasource([FromBody]DataManagerRequest dm) { var DataSource = _context.Organization.ToList(); if (dm.Where != null && dm.Where.Count > 0) //Filtering { // when expanding the TreeView node, it loads the corresponding child data. DataSource = DataSource.FindAll(x => x.ParentId == Convert.ToInt32(dm.Where[0].value)).ToList(); } else { // Initial loading, loads only the parent node. DataSource = DataSource.Where(or => or.ParentId == null).ToList(); } return Json(DataSource); } |
Also, refer the below documentation links for further reference.
https://ej2.syncfusion.com/aspnetcore/documentation/treeview/data-binding#remote-data
https://ej2.syncfusion.com/aspnetcore/TreeView/RemoteData#/material3
Regards,
Leo Lavanya Dhanaraj
Hi Leo,
Thanks for quick response.
Unfortunately, this does not help. I said I am using razor page, meaning razor views, but you gave me example for MVC.
I tweaked a little bit UrlDatasource method from your example, but I am getting 400 error (Bad request). I can't even reach breakpoint set on method below.
Here is my version for razor page:
public JsonResult OnPostUrlDatasource([FromBody]DataManagerRequest dm)
{
var DataSource = GetCampuses();
if (dm.Where != null && dm.Where.Count > 0) //Filtering
{
// when expanding the TreeView node, it loads the corresponding child data.
DataSource = DataSource.FindAll(x => x.ParentId == Convert.ToInt32(dm.Where[0].value)).ToList();
}
else
{
// Initial loading, loads only the parent node.
DataSource = DataSource.Where(or => or.ParentId == null).ToList();
}
return new JsonResult(DataSource);
}
I also tweaked classes from my initial post so that they mimic your Organization model class.
For example:
public class Campus
{
public int Id { get; set; }
public int? ParentId { get; set; }
public string Name { get; set; }
public bool? IsExpanded { get; set; }
public bool? HasChild { get; set; }
}
Hi Menusud,
We have prepared TreeView component with URL Adaptor sample to meet your requirement in the ASP.NET Core with razor page. We would like to let you know that, in the core with razor page the Antiforgery token validation enabled by default. So, that you are facing an issue not hitting the post method in the service.
For resolving this issue, we need to pass the Antiforgery token in the data manager request. Refer to the below code snippet,
[Index.cshtml]
|
@page "{handler?}" @using Microsoft.AspNetCore.Antiforgery; @model IndexModel
@{ ViewData["Title"] = "Home page"; }
@inject IAntiforgery antiforgery
@{ var token = antiforgery.GetAndStoreTokens(HttpContext).RequestToken; List<Dictionary<string, object>> list = new List<Dictionary<string, object>> { new Dictionary<string, object> { { "XSRF-TOKEN", @token } } }; Object[] array = list.ToArray(); }
<ejs-treeview id="tree"> <e-treeview-fields id="id" text="name" parentId="parentId" hasChildren="hasChild" expanded="expanded"> <e-data-manager url="/Index?handler=DataSource" adaptor="UrlAdaptor" crossDomain="true" headers=@array></e-data-manager> </e-treeview-fields> </ejs-treeview>
|
[Index.cshtml.cs]
|
public JsonResult OnPostDataSource([FromBody] DataManagerRequest dm) // bind dataSource with server side operations { if (listdata.Count == 0) { SelfData(); } DataOperations operation = new DataOperations(); List<localData> DataSource = listdata; if (dm.Where != null && dm.Where.Count > 0) //Filtering { // when expanding the TreeView node, it loads the corresponding child data. DataSource = operation.PerformFiltering(DataSource, dm.Where, dm.Where[0].Operator).ToList(); } else { // Initial loading, loads only the parent node. DataSource = DataSource.Where(or => or.parentId == null).ToList(); } return new JsonResult(new { result = DataSource }); } |
Also need to register header name in startup/program.cs file.
[Program.cs]
|
var builder = WebApplication.CreateBuilder(args);
// Add services to the container. builder.Services.AddRazorPages(); builder.Services.AddAntiforgery(o => o.HeaderName = "XSRF-TOKEN");
var app = builder.Build(); |
Attached the sample.
Regards,
Muthukrishnan K
Hello,
Adding token to the header did the trick. Now I can pass data to the treeview. However, I am struggling to properly display the data. I am expecting to be able to drill down through the structure: Campus->Building->Floor->Room, but I see this on my razor view page:
As you can see there are no buildings, no floors, no rooms.
TreeView control on page is:
<ejs-treeview id="listdata" loadOnDemand="false" showCheckBox="true" > <e-treeview-fields id="Id" text="Name" parentID="ParentId" hasChildren="HasChild" expanded="false">
<e-data-manager url="/Cora/Create?handler=UrlDatasource" adaptor="UrlAdaptor" crossDomain="true" headers=@array></e-data-manager>
</e-treeview-fields>
</ejs-treeview>
UrlDatasource method:
public JsonResult OnPostUrlDatasource(DataManagerRequest dm)
{
var DataSource = GetLocations();
if (dm.Where != null && dm.Where.Count > 0) //Filtering
{
DataSource = DataSource.FindAll(x => x.ParentId == Convert.ToInt32(dm.Where[0].value)).ToList();
}
else
{
DataSource = DataSource.Where(or => or.ParentId == null).ToList();
}
return new JsonResult(DataSource);
}
This method returns list that could be represented like this:
I can't figure out why TreeView control keeps repeating campuses only instead of displaying all data (campuses, buildings, floors and rooms).
Thanks for help
Is there any update on the issue?
Hi Menusud,
We have rendered the TreeView component with same as your mentioned structure. But the issue was not reproduced in our end. We suspect that you have may be added the node data multiple times to the TreeView component. Also, we have found that you have assigned false value to expanded field instead of mapping the expanded fields.
We have attached the sample to meet your requirement, please check it.
Refer to the output screenshot of the attached sample.
|
|
If the issue persists, replicate your issue in the attached sample or share the issue replicating sample. It will be help us to provide you the prompt solution.
Regards,
Muthukrishnan K