From b004ffdc244f27d3db5b96d4713d2891c5187f90 Mon Sep 17 00:00:00 2001 From: Steve Sanderson Date: Thu, 30 Aug 2018 10:26:57 +0100 Subject: [PATCH] Set BrowserHttpMessageHandler as the default handler when running on Mono WebAssembly --- .../Hosting/WebAssemblyHost.cs | 34 +++++++++++++++++++ .../Hosting/WebAssemblyHostBuilder.cs | 3 +- .../targets/BuiltInBclLinkerDescriptor.xml | 5 ++- 3 files changed, 37 insertions(+), 5 deletions(-) diff --git a/src/Microsoft.AspNetCore.Blazor.Browser/Hosting/WebAssemblyHost.cs b/src/Microsoft.AspNetCore.Blazor.Browser/Hosting/WebAssemblyHost.cs index 270b5cc42d..234d10b5b6 100644 --- a/src/Microsoft.AspNetCore.Blazor.Browser/Hosting/WebAssemblyHost.cs +++ b/src/Microsoft.AspNetCore.Blazor.Browser/Hosting/WebAssemblyHost.cs @@ -2,8 +2,11 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; +using System.Net.Http; +using System.Reflection; using System.Threading; using System.Threading.Tasks; +using Microsoft.AspNetCore.Blazor.Browser.Http; using Microsoft.AspNetCore.Blazor.Browser.Rendering; using Microsoft.Extensions.DependencyInjection; using Microsoft.JSInterop; @@ -36,6 +39,7 @@ namespace Microsoft.AspNetCore.Blazor.Hosting // JSRuntime in the 'root' execution context which implies that we want to do as part of a direct // call from Program.Main, and before any 'awaits'. JSRuntime.SetCurrentJSRuntime(_runtime); + SetBrowserHttpMessageHandlerAsDefault(); var scopeFactory = Services.GetRequiredService(); _scope = scopeFactory.CreateScope(); @@ -97,5 +101,35 @@ namespace Microsoft.AspNetCore.Blazor.Hosting { (Services as IDisposable)?.Dispose(); } + + private static void SetBrowserHttpMessageHandlerAsDefault() + { + // Within the Mono WebAssembly BCL, this is a special private static field + // that can be assigned to override the default handler + const string getHttpMessageHandlerFieldName = "GetHttpMessageHandler"; + var getHttpMessageHandlerField = typeof(HttpClient).GetField( + getHttpMessageHandlerFieldName, + BindingFlags.Static | BindingFlags.NonPublic); + + // getHttpMessageHandlerField will be null in tests, but nonnull when actually + // running under Mono WebAssembly + if (getHttpMessageHandlerField != null) + { + // Just in case you're not actually using HttpClient, defer the construction + // of the BrowserHttpMessageHandler + var handlerSingleton = new Lazy( + () => new BrowserHttpMessageHandler()); + Func handlerFactory = () => handlerSingleton.Value; + getHttpMessageHandlerField.SetValue(null, handlerFactory); + } + else + { + // We log a warning in case this ever happens at runtime (even though there's + // no obvious way it could be possible), but don't actually throw because that + // would break unit tests + Console.WriteLine("WARNING: Could not set default HttpMessageHandler because " + + $"'{getHttpMessageHandlerFieldName}' was not found on '{typeof(HttpClient).FullName}'."); + } + } } } diff --git a/src/Microsoft.AspNetCore.Blazor.Browser/Hosting/WebAssemblyHostBuilder.cs b/src/Microsoft.AspNetCore.Blazor.Browser/Hosting/WebAssemblyHostBuilder.cs index 40b1a4d2a6..3ea908ec8e 100644 --- a/src/Microsoft.AspNetCore.Blazor.Browser/Hosting/WebAssemblyHostBuilder.cs +++ b/src/Microsoft.AspNetCore.Blazor.Browser/Hosting/WebAssemblyHostBuilder.cs @@ -4,7 +4,6 @@ using System; using System.Collections.Generic; using System.Net.Http; -using Microsoft.AspNetCore.Blazor.Browser.Http; using Microsoft.AspNetCore.Blazor.Browser.Services; using Microsoft.AspNetCore.Blazor.Services; using Microsoft.Extensions.DependencyInjection; @@ -75,7 +74,7 @@ namespace Microsoft.AspNetCore.Blazor.Hosting { // Creating the URI helper needs to wait until the JS Runtime is initialized, so defer it. var uriHelper = s.GetRequiredService(); - return new HttpClient(new BrowserHttpMessageHandler()) + return new HttpClient { BaseAddress = new Uri(BrowserUriHelper.Instance.GetBaseUri()) }; diff --git a/src/Microsoft.AspNetCore.Blazor.Build/targets/BuiltInBclLinkerDescriptor.xml b/src/Microsoft.AspNetCore.Blazor.Build/targets/BuiltInBclLinkerDescriptor.xml index e441460d38..bda3b13a5e 100644 --- a/src/Microsoft.AspNetCore.Blazor.Build/targets/BuiltInBclLinkerDescriptor.xml +++ b/src/Microsoft.AspNetCore.Blazor.Build/targets/BuiltInBclLinkerDescriptor.xml @@ -16,11 +16,10 @@ - - - + +