Skip to content

GraphClientFactory.Create() throws exception on browser (Blazor WASM) #966

@LSDerekTardiff

Description

@LSDerekTardiff

Describe the bug

An exception is thrown when calling GraphClientFactory.Create() from a Blazor WASM web app (.NET 8).
From my investigation this is due to the call it makes to GetNativePlatformHttpHandler(IWebProxy proxy = null) which fails when trying to use SocketsHttpHandler which is incompatible when running on a browser.

crit: Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100]
      Unhandled exception rendering component: Operation is not supported on this platform.
System.PlatformNotSupportedException: Operation is not supported on this platform.
   at System.Net.Http.SocketsHttpHandler.set_Proxy(IWebProxy value)
   at Microsoft.Graph.GraphClientFactory.GetNativePlatformHttpHandler(IWebProxy proxy)
   at Microsoft.Graph.GraphClientFactory.Create(IEnumerable`1 handlers, String version, String nationalCloud, IWebProxy proxy, HttpMessageHandler finalHandler, Boolean disposeHandler)
   at Microsoft.Graph.GraphClientFactory.Create(GraphClientOptions graphClientOptions, String version, String nationalCloud, IWebProxy proxy, HttpMessageHandler finalHandler)
   at GraphBrowserBug.Pages.Home.TestGraphClientAsync() in D:\devl\GraphBrowserBug\Pages\Home.razor:line 18
   at GraphBrowserBug.Pages.Home.<BuildRenderTree>b__0_1() in D:\devl\GraphBrowserBug\Pages\Home.razor:line 7
   at Microsoft.AspNetCore.Components.ComponentBase.CallStateHasChangedOnAsyncCompletion(Task task)
   at Microsoft.AspNetCore.Components.RenderTree.Renderer.GetErrorHandledTask(Task taskToHandle, ComponentState owningComponentState)

This issue is mostly a problem when trying to create a BatchRequestContentCollection which eventually makes the call to GraphClientFactory.Create() which makes it impossible to use at the moment.

Here is the chuck of code in question from the file GraphClientFactory.cs. Perhaps the fix is to exclude browser clients from using the SocketsHttpHandler in here as it is done with other clients.

        internal static HttpMessageHandler GetNativePlatformHttpHandler(IWebProxy proxy = null)
        {
#if IOS || MACCATALYST
            return new NSUrlSessionHandler { AllowAutoRedirect = false };
#elif MACOS
            return new Foundation.NSUrlSessionHandler { AllowAutoRedirect = false };
#elif ANDROID
            return new Xamarin.Android.Net.AndroidMessageHandler { Proxy = proxy, AllowAutoRedirect = false, AutomaticDecompression = DecompressionMethods.All };
#elif NETFRAMEWORK
            // If custom proxy is passed, the WindowsProxyUsePolicy will need updating
            // https://github.com/dotnet/runtime/blob/main/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpHandler.cs#L575
            var proxyPolicy = proxy != null ? WindowsProxyUsePolicy.UseCustomProxy : WindowsProxyUsePolicy.UseWinHttpProxy;
            return new WinHttpHandler { Proxy = proxy, AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate , WindowsProxyUsePolicy = proxyPolicy, SendTimeout = Timeout.InfiniteTimeSpan, ReceiveDataTimeout = Timeout.InfiniteTimeSpan, ReceiveHeadersTimeout = Timeout.InfiniteTimeSpan };
#elif NET6_0_OR_GREATER
            //use resilient configs when we can https://learn.microsoft.com/en-us/aspnet/core/fundamentals/http-requests?view=aspnetcore-5.0#alternatives-to-ihttpclientfactory-1
            return new SocketsHttpHandler { Proxy = proxy, AllowAutoRedirect = false, AutomaticDecompression = DecompressionMethods.All, PooledConnectionLifetime = TimeSpan.FromMinutes(1)};
#else
            return new HttpClientHandler { Proxy = proxy, AllowAutoRedirect = false, AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate };
#endif
        }

Sample Project to reproduce the bug if required: https://github.com/LSDerekTardiff/GraphBrowserBug

Expected behavior

Calling GraphClientFactory.Create() does not throw an exception. And HttpClient is created.

How to reproduce

Sample Project to reproduce the bug: https://github.com/LSDerekTardiff/GraphBrowserBug
Just click the button on the homepage to execute the code in question.

SDK Version

3.2.3.0

Latest version known to work for scenario above?

No response

Known Workarounds

Since I am using a Kiota generated client I simply added the required batch requests to my client with the necessary modifications to get this working.
However I would prefer not to have to maintain these changes.

Debug output

Click to expand log ``` crit: Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100] Unhandled exception rendering component: Operation is not supported on this platform. System.PlatformNotSupportedException: Operation is not supported on this platform. at System.Net.Http.SocketsHttpHandler.set_Proxy(IWebProxy value) at Microsoft.Graph.GraphClientFactory.GetNativePlatformHttpHandler(IWebProxy proxy) at Microsoft.Graph.GraphClientFactory.Create(IEnumerable`1 handlers, String version, String nationalCloud, IWebProxy proxy, HttpMessageHandler finalHandler, Boolean disposeHandler) at Microsoft.Graph.GraphClientFactory.Create(GraphClientOptions graphClientOptions, String version, String nationalCloud, IWebProxy proxy, HttpMessageHandler finalHandler) at GraphBrowserBug.Pages.Home.TestGraphClientAsync() in D:\devl\GraphBrowserBug\Pages\Home.razor:line 18 at GraphBrowserBug.Pages.Home.b__0_1() in D:\devl\GraphBrowserBug\Pages\Home.razor:line 7 at Microsoft.AspNetCore.Components.ComponentBase.CallStateHasChangedOnAsyncCompletion(Task task) at Microsoft.AspNetCore.Components.RenderTree.Renderer.GetErrorHandledTask(Task taskToHandle, ComponentState owningComponentState)
</details>


### Configuration

- OS: Windows 11
- Arch: x64
Specific to Browser based projects in my case Blazor WASM

### Other information

_No response_

Metadata

Metadata

Assignees

Labels

type:bugA broken experience

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions