I updated an existing Preview 4 project.
I added:
builder.Services.AddHttpClient("BlazorApp5.ServerAPI", client => client.BaseAddress = new Uri(builder.HostEnvironment.BaseAddress))
.AddHttpMessageHandler<BaseAddressAuthorizationMessageHandler>();
// Supply HttpClient instances that include access tokens when making requests to the server project
builder.Services.AddTransient(sp => sp.GetRequiredService<IHttpClientFactory>().CreateClient("BlazorApp5.ServerAPI"));
And i removed
builder.Services.AddSingleton(new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
The Fetch Data example is now running with
try
{
forecasts = await Http.GetFromJsonAsync<WeatherForecast[]>("WeatherForecast");
}
catch (AccessTokenNotAvailableException exception)
{
exception.Redirect();
}
But the razor Components that not have [Authorize] and the Controller methods without [Authorize] run now in an AccessTokenNotAvailableException.
I also have this problem. To try allow unprotected pages/api access.
@javiercn Any update on how to allow access to anonymous endpoints?
@mihaimyh I found the best way to achieve this currently is to inject a named instance of httpclient via IHttpClientFactory onto the page to create a new token free instance.
Here's my code:
Client program.cs
builder.Services.AddHttpClient("CustomClient", client =>
client.BaseAddress = new Uri(builder.HostEnvironment.BaseAddress));
Razor page:
@inject IHttpClientFactory Client
...
await Client.CreateClient("CustomClient").PostAsJsonAsync
Let me know if you need further assistance on this one.
@mihaimyh I found the best way to achieve this currently is to inject a named instance of httpclient via IHttpClientFactory onto the page to create a new token free instance.
Here's my code:Client program.cs
builder.Services.AddHttpClient("CustomClient", client => client.BaseAddress = new Uri(builder.HostEnvironment.BaseAddress));Razor page:
@inject IHttpClientFactory Client ... await Client.CreateClient("CustomClient").PostAsJsonAsyncLet me know if you need further assistance on this one.
I am already doing this but currently the app is trying to authenticate the user on the first load of the page.
Is there a way to allow anonymous access?
Just make sure it doesn't have an @attribute and it should be fine I would've thought.
My pages don't ask for auth unless I put [Authorize] on the page or controller.
I did achieve this similar:
I created a class AuthHttpClient:
public class AuthHttpClient : HttpClient { }
And in Program.cs:
builder.Services.AddHttpClient<AuthHttpClient>(client => client.BaseAddress = new Uri(builder.HostEnvironment.BaseAddress)) .AddHttpMessageHandler<BaseAddressAuthorizationMessageHandler>(); builder.Services.AddSingleton(new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) }); builder.Services.AddApiAuthorization();
I don't know if that is the best practices and the best way to have 2 clients, one with BaseAddressAuthorizationMessageHandler and one without.
@javiercn Any guidance on this issue, please?
I did achieve this similar:
I created a class AuthHttpClient:public class AuthHttpClient : HttpClient { }And in Program.cs:
builder.Services.AddHttpClient<AuthHttpClient>(client => client.BaseAddress = new Uri(builder.HostEnvironment.BaseAddress)) .AddHttpMessageHandler<BaseAddressAuthorizationMessageHandler>(); builder.Services.AddSingleton(new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) }); builder.Services.AddApiAuthorization();I don't know if that is the best practices and the best way to have 2 clients, one with BaseAddressAuthorizationMessageHandler and one without.
Following this worked for me on the final release which caused me the same issue. But same question: Is this the best practice? Some final answer to this?
@mihaimyh I found the best way to achieve this currently is to inject a named instance of httpclient via IHttpClientFactory onto the page to create a new token free instance.
Here's my code:Client program.cs
builder.Services.AddHttpClient("CustomClient", client => client.BaseAddress = new Uri(builder.HostEnvironment.BaseAddress));Razor page:
@inject IHttpClientFactory Client ... await Client.CreateClient("CustomClient").PostAsJsonAsyncLet me know if you need further assistance on this one.
This worked for me
But still same question: Is this the best practice?
@Sagar-Vaja I saw Chris come up with a slightly cleaner way:
https://chrissainty.com/avoiding-accesstokennotavailableexception-when-using-blazor-webassembly-hosted-template-with-individual-user-accounts/
Using a separate client for talking to public endpoints is still the right choice, and what we consider best practice. Using a typed client is an option here as Chriss suggests. I would say that if you go that route, you might as well just define methods to get the results you want within that class instead of just grabbing the client.
We'll add this guidance to the docs.
Thank you for contacting us. Due to a lack of activity on this discussion issue we're closing it in an effort to keep our backlog clean. If you believe there is a concern related to the ASP.NET Core framework, which hasn't been addressed yet, please file a new issue.
This issue will be locked after 30 more days of inactivity. If you still wish to discuss this subject after then, please create a new issue!
Most helpful comment
Using a separate client for talking to public endpoints is still the right choice, and what we consider best practice. Using a typed client is an option here as Chriss suggests. I would say that if you go that route, you might as well just define methods to get the results you want within that class instead of just grabbing the client.
We'll add this guidance to the docs.