Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 62 additions & 24 deletions BlazorWebAssemblyXrefGenerator/Pages/Home.razor
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
@page "/"
@using System.Net
@using System.Text
@using System.Text.RegularExpressions
@inject IHttpClientFactory ClientFactory

Expand All @@ -10,17 +11,6 @@
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">Search</h3>
<span style="float:right">
<InputSelect @bind-Value="dotNetVersion">
<option>aspnetcore-10.0</option>
<option>aspnetcore-9.0</option>
<option>aspnetcore-8.0</option>
<option>aspnetcore-7.0</option>
<option>aspnetcore-6.0</option>
<option>aspnetcore-5.0</option>
<option>aspnetcore-3.1</option>
</InputSelect>
</span>
</div>
<div class="panel-body">
<div class="form-group">
Expand Down Expand Up @@ -68,21 +58,42 @@
private SearchResults? SearchResultItems { get; set; }
private List<Result> ResultsToRender { get; set; } = new();
public string? message;
private string? dotNetVersion;

private const int MaxResults = 22;

private bool isSearching = false;

private static readonly Regex NestedBracketRegex = new Regex(
@"\[(?:[^\[\]]+|(?<Open>\[)|(?<-Open>\]))*(?(Open)(?!))\]",
RegexOptions.Compiled
);

private static readonly Regex TypeSegmentRegex = new Regex(
@"(?<=-)(\d+)",
RegexOptions.Compiled
);

private static readonly Regex NestedAngleBracketRegex = new Regex(
@"<(?:[^<>]+|(?<Open><)|(?<-Open>>))*(?(Open)(?!))>",
RegexOptions.Compiled
);

private static readonly Regex NestedParenthesesRegex = new Regex(
@"\((?:[^()]+|(?<Open>\()|(?<-Open>\)))+(?(Open)(?!))\)",
RegexOptions.Compiled
);

protected override void OnInitialized() => Model ??= new();

public async Task GetSearchResults()
{

isSearching = true;
ResultsToRender.Clear();
message = string.Empty;

var apiClient = ClientFactory.CreateClient("APIClient");

if (string.IsNullOrEmpty(Model?.SearchText) || apiClient == null)
{
isSearching = false;
Expand All @@ -91,26 +102,49 @@

try
{
SearchResultItems = await apiClient.GetFromJsonAsync<SearchResults>($"api/apibrowser/dotnet/search?api-version=0.2&search={Model.SearchText}");
var urlEncodedSearchText = WebUtility.UrlEncode(Model.SearchText);

SearchResultItems = await apiClient.GetFromJsonAsync<SearchResults>($"api/apibrowser/dotnet/search?search={urlEncodedSearchText}");

if (SearchResultItems?.Results?.Any() == true)
{
var index = 1;
foreach (var result in SearchResultItems.Results.Take(MaxResults))
{
var client = ClientFactory.CreateClient();
var encodedUrl = WebUtility.UrlEncode($"https://learn.microsoft.com/en-us{result.Url}?view={dotNetVersion}");
using var request = new HttpRequestMessage(HttpMethod.Get, $"https://corsproxy.io/?{encodedUrl}");
using var response = await client.SendAsync(request);
var content = await response.Content.ReadAsStringAsync();

var match = Regex.Match(content, "<meta name=\"ms.assetid\" content=\"(.+?)\" />");
if (match.Success)
if (!string.IsNullOrEmpty(result.DisplayName) && !string.IsNullOrEmpty(result.Url))
{
result.Link = match.Groups[1].Value.Replace("*", "%2A").Replace("`", "%60");
if (result.ItemType == "Constructor")
{
result.Link = Regex.Replace(result.DisplayName, @"\(.*\)", ".%23ctor%2A");
//result.Link = NestedParenthesesRegex.Replace(result.Link, ".%23ctor%2A");
}
else if (result.ItemType == "Method")
{

result.Link = Regex.Replace(result.DisplayName, @"\(.*\)", "%2A");
//result.Link = NestedParenthesesRegex.Replace(result.Link, ".%2A");
}
else if (result.ItemType == "Property")
{
result.Link = NestedBracketRegex.Replace(result.DisplayName, "%2A");
}
else
{
result.Link = result.DisplayName;
}

var captureTypeSegmentMatch = TypeSegmentRegex.Match(result.Url).Value;

if (captureTypeSegmentMatch is not null)
{
result.Link = Regex.Replace(result.Link, @"<.*>", $"%60{captureTypeSegmentMatch}");

//var angleBracketMatch = NestedAngleBracketRegex.Match(result.DisplayName);
//var angleBracketMatchValue = angleBracketMatch.Value;
//result.Link = NestedAngleBracketRegex.Replace(result.DisplayName, $"%60{angleBracketMatchValue}");
}
}

result.Index = index++;
result.Index = ResultsToRender.Count + 1;
ResultsToRender.Add(result);
StateHasChanged();
}
Expand All @@ -124,6 +158,10 @@
{
message = "Bad Request! No results returned.";
}
catch (HttpRequestException ex)
{
message = $"A general error occurred. {ex.Message}";
}
finally
{
isSearching = false;
Expand Down
2 changes: 1 addition & 1 deletion BlazorWebAssemblyXrefGenerator/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@

builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });

builder.Services.AddHttpClient("APIClient", client => client.BaseAddress = new Uri("https://learn.microsoft.com"));
builder.Services.AddHttpClient("APIClient", client => client.BaseAddress = new Uri("https://learn.microsoft.com/"));

await builder.Build().RunAsync();
Loading