Skip to content

Commit

Permalink
WIP: Add more logging for BlazorWebView
Browse files Browse the repository at this point in the history
Fixes #9792
  • Loading branch information
Eilon committed Dec 29, 2022
1 parent 61e4215 commit d32a5a5
Show file tree
Hide file tree
Showing 10 changed files with 89 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@
<ProjectReference Include="..\WebViewAppShared\WebViewAppShared.csproj" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging.Debug" />
</ItemGroup>

<Import Project="..\..\src\WindowsForms\build\Microsoft.AspNetCore.Components.WebView.WindowsForms.targets" />

</Project>
7 changes: 7 additions & 0 deletions src/BlazorWebView/samples/BlazorWinFormsApp/Form1.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using Microsoft.AspNetCore.Components.Web;
using Microsoft.AspNetCore.Components.WebView.WindowsForms;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using WebViewAppShared;

namespace BlazorWinFormsApp
Expand All @@ -17,6 +18,12 @@ public partial class Form1 : Form
public Form1()
{
var services1 = new ServiceCollection();
services1.AddLogging(c =>
{
c.AddDebug();
// Enable maximum logging for BlazorWebView
c.AddFilter("Microsoft.AspNetCore.Components.WebView", LogLevel.Trace);
});
services1.AddWindowsFormsBlazorWebView();
#if DEBUG
services1.AddBlazorWebViewDeveloperTools();
Expand Down
4 changes: 4 additions & 0 deletions src/BlazorWebView/samples/BlazorWpfApp/BlazorWpfApp.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@
<ProjectReference Include="..\WebViewAppShared\WebViewAppShared.csproj" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging.Debug" />
</ItemGroup>

<Import Project="..\..\src\Wpf\build\Microsoft.AspNetCore.Components.WebView.Wpf.targets" />

</Project>
7 changes: 7 additions & 0 deletions src/BlazorWebView/samples/BlazorWpfApp/MainWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.Windows;
using Microsoft.AspNetCore.Components.Web;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using WebViewAppShared;

namespace BlazorWpfApp
Expand All @@ -18,6 +19,12 @@ public partial class MainWindow : Window
public MainWindow()
{
var services1 = new ServiceCollection();
services1.AddLogging(c =>
{
c.AddDebug();
// Enable maximum logging for BlazorWebView
c.AddFilter("Microsoft.AspNetCore.Components.WebView", LogLevel.Trace);
});
services1.AddWpfBlazorWebView();
#if DEBUG
services1.AddBlazorWebViewDeveloperTools();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using Microsoft.AspNetCore.Components.WebView.WebView2;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.FileProviders;
using Microsoft.Extensions.Logging;
using Microsoft.Maui.Dispatching;
using Microsoft.Maui.Handlers;
using WebView2Control = Microsoft.UI.Xaml.Controls.WebView2;
Expand Down Expand Up @@ -56,11 +57,14 @@ private void StartWebViewCoreIfPossible()
throw new InvalidOperationException($"Can't start {nameof(BlazorWebView)} without native web view instance.");
}

var logger = Services!.GetService<ILogger<BlazorWebView>>();

// We assume the host page is always in the root of the content directory, because it's
// unclear there's any other use case. We can add more options later if so.
var contentRootDir = Path.GetDirectoryName(HostPage!) ?? string.Empty;
var hostPageRelativePath = Path.GetRelativePath(contentRootDir, HostPage!);

logger?.LogDebug("Creating file provider at content root '{CONTENT_ROOT}', using host page relative path '{HOST_PAGE_PATH}'.", contentRootDir, hostPageRelativePath);
var fileProvider = VirtualView.CreateFileProvider(contentRootDir);

_webviewManager = new WinUIWebViewManager(
Expand All @@ -79,10 +83,14 @@ private void StartWebViewCoreIfPossible()
{
foreach (var rootComponent in RootComponents)
{
logger?.LogDebug("Adding root component '{ROOT_COMPONENT_TYPE}' with selector '{SELECTOR}'. Number of parameters: {PARAMETER_COUNT}", rootComponent.ComponentType?.FullName, rootComponent.Selector, rootComponent.Parameters?.Count ?? 0);

// Since the page isn't loaded yet, this will always complete synchronously
_ = rootComponent.AddToWebViewManagerAsync(_webviewManager);
}
}

logger?.LogDebug("Starting initial navigation to '{START_PATH}'.", VirtualView.StartPath);
_webviewManager.Navigate(VirtualView.StartPath);
}

Expand Down
13 changes: 13 additions & 0 deletions src/BlazorWebView/src/Maui/Windows/WinUIWebViewManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using Microsoft.AspNetCore.Components.Web;
using Microsoft.AspNetCore.Components.WebView.WebView2;
using Microsoft.Extensions.FileProviders;
using Microsoft.Extensions.Logging;
using Microsoft.Web.WebView2.Core;
using Windows.ApplicationModel;
using Windows.Storage.Streams;
Expand Down Expand Up @@ -77,13 +78,16 @@ protected override async Task HandleWebResourceRequest(CoreWebView2WebResourceRe

var requestUri = QueryStringHelper.RemovePossibleQueryString(eventArgs.Request.Uri);

_logger?.LogDebug("Handling web request to URI '{URI}'.", requestUri);

// First, call into WebViewManager to see if it has a framework file for this request. It will
// fall back to an IFileProvider, but on WinUI it's always a NullFileProvider, so that will never
// return a file.
if (TryGetResponseContent(requestUri, allowFallbackOnHostPage, out var statusCode, out var statusMessage, out var content, out var headers)
&& statusCode != 404)
{
var headerString = GetHeaderString(headers);
_logger?.LogDebug("Response content being sent for web request to URI '{URI}'.", requestUri);
eventArgs.Response = _coreWebView2Environment!.CreateWebResourceResponse(content.AsRandomAccessStream(), statusCode, statusMessage, headerString);
}
else if (new Uri(requestUri) is Uri uri && AppOriginUri.IsBaseOf(uri))
Expand Down Expand Up @@ -130,12 +134,19 @@ protected override async Task HandleWebResourceRequest(CoreWebView2WebResourceRe
if (stream != null)
{
var headerString = GetHeaderString(headers);

_logger?.LogDebug("Response content being sent for web request to URI '{URI}' with HTTP status code {HTTP_STATUS_CODE}.", requestUri, statusCode);

eventArgs.Response = _coreWebView2Environment!.CreateWebResourceResponse(
stream,
statusCode,
statusMessage,
headerString);
}
else
{
_logger?.LogDebug("Response content was not found for web request to URI '{URI}'.", requestUri);
}

async Task<IRandomAccessStream> CopyContentToRandomAccessStreamAsync(Stream content)
{
Expand All @@ -157,6 +168,8 @@ protected override void QueueBlazorStart()
// In .NET MAUI we use autostart='false' for the Blazor script reference, so we start it up manually in this event
_webview.CoreWebView2.DOMContentLoaded += async (_, __) =>
{
_logger?.LogDebug("Calling Blazor.start() in the WebView2.");

await _webview.CoreWebView2!.ExecuteScriptAsync(@"
Blazor.start();
");
Expand Down
28 changes: 26 additions & 2 deletions src/BlazorWebView/src/SharedSource/WebView2WebViewManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
using Microsoft.AspNetCore.Components.Web;
using Microsoft.AspNetCore.Components.WebView;
using Microsoft.Extensions.FileProviders;
using Microsoft.Extensions.Logging;
#if WEBVIEW2_WINFORMS
using System.Diagnostics;
using Microsoft.AspNetCore.Components.WebView.WindowsForms;
Expand All @@ -31,6 +32,7 @@
using Microsoft.Web.WebView2.Core;
using WebView2Control = Microsoft.Web.WebView2.Wpf.WebView2;
using System.Reflection;
using System.Security.Policy;
#elif WEBVIEW2_MAUI
using Microsoft.AspNetCore.Components.WebView.Maui;
using Microsoft.Extensions.DependencyInjection;
Expand Down Expand Up @@ -60,7 +62,7 @@ internal class WebView2WebViewManager : WebViewManager
protected static readonly string AppOrigin = $"https://{AppHostAddress}/";

internal static readonly Uri AppOriginUri = new(AppOrigin);

protected readonly ILogger<WebView2WebViewManager>? _logger;
private readonly WebView2Control _webview;
private readonly Task<bool> _webviewReadyTask;
private readonly string _contentRootRelativeToAppRoot;
Expand Down Expand Up @@ -117,6 +119,8 @@ internal WebView2WebViewManager(
}
#endif

_logger = services.GetService<ILogger<WebView2WebViewManager>>();

_webview = webview;
_urlLoading = urlLoading;
_blazorWebViewInitializing = blazorWebViewInitializing;
Expand Down Expand Up @@ -165,6 +169,8 @@ BlazorWebViewHandler blazorWebViewHandler
$"Please add all the required services by calling '{nameof(IServiceCollection)}.{nameof(BlazorWebViewServiceCollectionExtensions.AddMauiBlazorWebView)}' in the application startup code.");
}

_logger = services.GetService<ILogger<WebView2WebViewManager>>();

_webview = webview;
_blazorWebViewHandler = blazorWebViewHandler;
_contentRootRelativeToAppRoot = contentRootRelativeToAppRoot;
Expand All @@ -185,6 +191,7 @@ protected override void NavigateCore(Uri absoluteUri)

if (isWebviewInitialized)
{
_logger?.LogDebug("Navigating to {URI}.", absoluteUri);
_webview.Source = absoluteUri;
}
});
Expand All @@ -211,14 +218,18 @@ private async Task<bool> TryInitializeWebView2()
}
catch (FileNotFoundException)
{
_logger?.LogDebug("Failed to create WebView2 environment. This could mean that WebView2 is not installed.");

// This method needs to be invoked even if the WebView2 Runtime is not installed,
// since it is reponsible for creating the warning label and WebView2 Runtime
// download link.
await _webview.EnsureCoreWebView2Async();
return false;
}

_logger?.LogDebug("Starting WebView2...");
await _webview.EnsureCoreWebView2Async();
_logger?.LogDebug("WebView2 is started.");

var developerTools = _blazorWebViewHandler.DeveloperTools;
#elif WEBVIEW2_WINFORMS || WEBVIEW2_WPF
Expand All @@ -228,9 +239,11 @@ private async Task<bool> TryInitializeWebView2()
browserExecutableFolder: args.BrowserExecutableFolder,
userDataFolder: userDataFolder,
options: args.EnvironmentOptions)
.ConfigureAwait(true);
.ConfigureAwait(true);

_logger?.LogDebug("Starting WebView2...");
await _webview.EnsureCoreWebView2Async(_coreWebView2Environment);
_logger?.LogDebug("WebView2 is started.");

var developerTools = _developerTools;
#endif
Expand Down Expand Up @@ -299,6 +312,8 @@ protected virtual Task HandleWebResourceRequest(CoreWebView2WebResourceRequested

var requestUri = QueryStringHelper.RemovePossibleQueryString(eventArgs.Request.Uri);

_logger?.LogDebug("Handling web request to URI '{URI}'.", requestUri);

if (TryGetResponseContent(requestUri, allowFallbackOnHostPage, out var statusCode, out var statusMessage, out var content, out var headers))
{
StaticContentHotReloadManager.TryReplaceResponseContent(_contentRootRelativeToAppRoot, requestUri, ref statusCode, ref content, headers);
Expand All @@ -307,8 +322,14 @@ protected virtual Task HandleWebResourceRequest(CoreWebView2WebResourceRequested

var autoCloseStream = new AutoCloseOnReadCompleteStream(content);

_logger?.LogDebug("Response content being sent for web request to URI '{URI}' with HTTP status code {HTTP_STATUS_CODE}.", requestUri, statusCode);

eventArgs.Response = _coreWebView2Environment!.CreateWebResourceResponse(autoCloseStream, statusCode, statusMessage, headerString);
}
else
{
_logger?.LogDebug("Response content was not found for web request to URI '{URI}'.", requestUri);
}
#elif WEBVIEW2_MAUI
// No-op here because all the work is done in the derived WinUIWebViewManager
#endif
Expand All @@ -333,6 +354,7 @@ private void CoreWebView2_NavigationStarting(object? sender, CoreWebView2Navigat
#elif WEBVIEW2_MAUI
_blazorWebViewHandler.UrlLoading(callbackArgs);
#endif
_logger?.LogDebug("Navigation event for URI '{URI}' with URL loading strategy '{URL_LOADING_STRATEGY}'.", uri, callbackArgs.UrlLoadingStrategy);

if (callbackArgs.UrlLoadingStrategy == UrlLoadingStrategy.OpenExternally)
{
Expand All @@ -356,6 +378,8 @@ private void CoreWebView2_NewWindowRequested(object? sender, CoreWebView2NewWind

private void LaunchUriInExternalBrowser(Uri uri)
{
_logger?.LogDebug("Launching external browser for URI '{URI}'.", uri);

#if WEBVIEW2_WINFORMS || WEBVIEW2_WPF
using (var launchBrowser = new Process())
{
Expand Down
8 changes: 8 additions & 0 deletions src/BlazorWebView/src/WindowsForms/BlazorWebView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
using Microsoft.AspNetCore.Components.WebView.WebView2;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.FileProviders;
using Microsoft.Extensions.Logging;
using WebView2Control = Microsoft.Web.WebView2.WinForms.WebView2;

namespace Microsoft.AspNetCore.Components.WebView.WindowsForms
Expand Down Expand Up @@ -162,6 +163,8 @@ private void StartWebViewCoreIfPossible()
return;
}

var logger = Services.GetService<ILogger<BlazorWebView>>();

// We assume the host page is always in the root of the content directory, because it's
// unclear there's any other use case. We can add more options later if so.
string appRootDir;
Expand All @@ -179,6 +182,7 @@ private void StartWebViewCoreIfPossible()
var contentRootRelativePath = Path.GetRelativePath(appRootDir, contentRootDirFullPath);
var hostPageRelativePath = Path.GetRelativePath(contentRootDirFullPath, hostPageFullPath);

logger?.LogDebug("Creating file provider at content root '{CONTENT_ROOT}', using host page relative path '{HOST_PAGE_PATH}'.", contentRootDirFullPath, hostPageRelativePath);
var fileProvider = CreateFileProvider(contentRootDirFullPath);

_webviewManager = new WebView2WebViewManager(
Expand All @@ -197,9 +201,13 @@ private void StartWebViewCoreIfPossible()

foreach (var rootComponent in RootComponents)
{
logger?.LogDebug("Adding root component '{ROOT_COMPONENT_TYPE}' with selector '{SELECTOR}'. Number of parameters: {PARAMETER_COUNT}", rootComponent.ComponentType.FullName, rootComponent.Selector, rootComponent.Parameters?.Count ?? 0);

// Since the page isn't loaded yet, this will always complete synchronously
_ = rootComponent.AddToWebViewManagerAsync(_webviewManager);
}

logger?.LogDebug("Starting initial navigation to '{START_PATH}'.", StartPath);
_webviewManager.Navigate(StartPath);
}

Expand Down
9 changes: 9 additions & 0 deletions src/BlazorWebView/src/Wpf/BlazorWebView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@
using System.Windows.Controls;
using System.Windows.Input;
using Microsoft.AspNetCore.Components.WebView.WebView2;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.FileProviders;
using Microsoft.Extensions.Logging;
using WebView2Control = Microsoft.Web.WebView2.Wpf.WebView2;

namespace Microsoft.AspNetCore.Components.WebView.Wpf
Expand Down Expand Up @@ -247,6 +249,8 @@ private void StartWebViewCoreIfPossible()
return;
}

var logger = Services.GetService<ILogger<BlazorWebView>>();

// We assume the host page is always in the root of the content directory, because it's
// unclear there's any other use case. We can add more options later if so.
string appRootDir;
Expand All @@ -264,6 +268,7 @@ private void StartWebViewCoreIfPossible()
var hostPageRelativePath = Path.GetRelativePath(contentRootDirFullPath, hostPageFullPath);
var contentRootDirRelativePath = Path.GetRelativePath(appRootDir, contentRootDirFullPath);

logger?.LogDebug("Creating file provider at content root '{CONTENT_ROOT}', using host page relative path '{HOST_PAGE_PATH}'.", contentRootDirFullPath, hostPageRelativePath);
var fileProvider = CreateFileProvider(contentRootDirFullPath);

_webviewManager = new WebView2WebViewManager(
Expand All @@ -282,9 +287,13 @@ private void StartWebViewCoreIfPossible()

foreach (var rootComponent in RootComponents)
{
logger?.LogDebug("Adding root component '{ROOT_COMPONENT_TYPE}' with selector '{SELECTOR}'. Number of parameters: {PARAMETER_COUNT}", rootComponent.ComponentType.FullName, rootComponent.Selector, rootComponent.Parameters?.Count ?? 0);

// Since the page isn't loaded yet, this will always complete synchronously
_ = rootComponent.AddToWebViewManagerAsync(_webviewManager);
}

logger?.LogDebug("Starting initial navigation to '{START_PATH}'.", StartPath);
_webviewManager.Navigate(StartPath);
}

Expand Down
3 changes: 3 additions & 0 deletions src/Controls/samples/Controls.Sample/MauiProgram.cs
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,9 @@ public static MauiApp CreateMauiApp()
#else
logging.AddConsole();
#endif

// Enable maximum logging for BlazorWebView
logging.AddFilter("Microsoft.AspNetCore.Components.WebView", LogLevel.Trace);
});

services.AddSingleton<ITextService, TextService>();
Expand Down

0 comments on commit d32a5a5

Please sign in to comment.