Regarding
Is there any other way to get all the site and subsites(All levels)
with minimal time and in a single call.
search based approach could be more suitable in this regard (at least from performance perspective) as demonstrated below:
public static List<WebInfo> GetAllWebs(ClientContext ctx)
{
var keywordQuery = new KeywordQuery(ctx)
{
QueryText = "contentclass:\"STS_Web\"",
RowLimit = 500,
StartRow = 0
};
keywordQuery.SelectProperties.Add("Title");
keywordQuery.SelectProperties.Add("SPWebUrl");
keywordQuery.SelectProperties.Add("Description");
var searchExec = new SearchExecutor(ctx);
var results = searchExec.ExecuteQuery(keywordQuery);
ctx.ExecuteQuery();
var resultTable = results.Value.FirstOrDefault();
if (resultTable == null)
return new List<WebInfo>();
return resultTable.ResultRows.Select(row => new WebInfo()
{
Title = (string) row["Title"],
Description = (string) row["Description"],
AbsUrl = (string) row["SPWebUrl"]
}).ToList();
}
where
class WebInfo
{
public string Title { get; set; }
public string AbsUrl { get; set; }
public string Description { get; set; }
}
Note: contentclass:"STS_Web"
query targets web in search results
References
Search API usage in the SharePoint add-in model
SharePoint Power Searching Using ContentClass