Now I understand everything. So, gRPC does not support IIS subpaths and we need to configure (HTTP2) handler:
public class GrpcSubdirectoryHandler : DelegatingHandler
{
private readonly Uri basePath;
public GrpcSubdirectoryHandler(HttpMessageHandler innerHandler, Uri basePath)
: base(innerHandler)
{
this.basePath = basePath;
}
protected override Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request, CancellationToken cancellationToken)
{
var old = request.RequestUri;
if (old == null)
{
return base.SendAsync(request, cancellationToken);
}
string url = $"{old.Scheme}://{old.Host}:{old.Port}{basePath.PathAndQuery}{old.AbsolutePath.TrimStart('/')}";
request.RequestUri = new Uri(url, UriKind.Absolute);
return base.SendAsync(request, cancellationToken);
}
}
Now channel:
var singleHttpHandler = new GrpcSubdirectoryHandler(new GrpcWebHandler(GrpcWebMode.GrpcWeb, new HttpClientHandler()), baseAddress);
builder.Services.AddSingleton(s =>
{
string baseUri = s.GetRequiredService<NavigationManager>().BaseUri;
var channel = GrpcChannel.ForAddress(baseUri, new GrpcChannelOptions { HttpHandler = singleHttpHandler });
var client = new PersonContract.PersonContractClient(channel);
return client;
});
Where GrpcWebHandler is absolutely important for HTTP2 usage. As for the rest of IIS subfolder routing, we can still enjoy full client-side WASM with all routing falling back, just that I need IIS subfolder input, it has to be solved on server-side CSHTML page. Since base tag is solved there, fallback just needs to be into that page:
app.MapFallbackToPage("/MainWASM");
__
@page
@model ANeT.WebGuard.Pages.MainWASMModel
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<title>WebGuard</title>
<base href="@(HttpContext.Request.PathBase + (HttpContext.Request.PathBase.Value?.EndsWith('/') == true ? string.Empty : "/"))" />
So, I will map everything to specific virtual PATH and then just use URL rewritting to fit any IIS installation my customers do. This is working and tested solution.