Session values cant be obtained between two different web api calls
I have two Web API methods called in different cases. I have used the SetString method and the value is set in method 1 but when the 2nd method is called for other cases, accessing the value using the GetString method it returns the value as null.
public string Method1(string args)
{
HttpContext.Session.SetString("key", "value"); // value is set in this method.
}
public string Method2(string args)
{
string value = HttpContext.Session.GetString("key"); // value is obtained as null here
}
Any suggestions to resolve this issue. I have added controller manually in the blazor server-side application for WebAPI call.
1 answer
-
answered 2021-01-17 13:42
Roar S.
Please make sure the following exists in
Startup
:Startup#ConfigureServices
services.AddSession(options => { options.IdleTimeout = System.TimeSpan.FromSeconds(120); // two minutes });
Startup#Configure
app.UseSession();
Please check here for ordering: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/app-state?view=aspnetcore-5.0
Important If you run your app on multiple instances, you'll need to choose a strategy. Storing sessions using Distributed Cache is preferable. More info: https://dzone.com/articles/aspnet-core-session-storage-strategies
Another way of solving multiple server issue, is to use sticky sessions on your load balancer. This is not recommended because of the risc of uneven spread of load.
If you are able to get rid of the need for sessions in your app, I would highly recommend that.
See also questions close to this topic
-
Huge amount of logon attempts when loading a page (without cache)
I notice in the Performance Monitor of Windows Server 2012 that there are spikes in logon attempts per second under Web Service -> Logon Attempts/sec. These spikes go from about 0 to 50.
I've traced this down to a page refresh. Loading a page with no cache that is. An average page load does about 50 requests (images, scripts, etc). Now apparently these 50 requests are shown as logon attempts.
Is this normal?
Note that this page does not require the visitor to be logged in.
-
Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler[3\
When warn: Microsoft.AspNetCore.DataProtection.Repositories.FileSystemXmlRepository[60]
Storing keys in a directory '/root/.aspnet/DataProtection-Keys' that may not be persisted outside of the container. Protected data will be unavailable when container is destroyed.
warn: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[35]
No XML encryptor configured. Key {e43b756a-2818-4898-8730-5e8e0f230be7} may be persisted to storage in unencrypted form.
info: IdentityServer4.Startup[0]
Starting IdentityServer4 version 4.1.1+cebd52f5bc61bdefc262fd20739d4d087c6f961f
info: IdentityServer4.Startup[0]
You are using the in-memory version of the persisted grant store. This will store consent decisions, authorization codes, refresh and reference tokens in memory only. If you are using any of those features in production, you want to switch to a different store implementation.
info: IdentityServer4.Startup[0]
Using the default authentication scheme Identity.Application for IdentityServer
info: Microsoft.Hosting.Lifetime[0]
Now listening on: https://[::]:8081
info: Microsoft.Hosting.Lifetime[0]
Now listening on: http://[::]:8080
info: Microsoft.Hosting.Lifetime[0]
Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
Hosting environment: Production
info: Microsoft.Hosting.Lifetime[0]
Content root path: /app
info: IdentityServer4.Hosting.IdentityServerMiddleware[0]
Invoking IdentityServer endpoint: IdentityServer4.Endpoints.TokenEndpoint for /connect/token
info: IdentityServer4.AspNetIdentity.ResourceOwnerPasswordValidator[0]
Credentials validated for username: muthu
info: IdentityServer4.Validation.TokenRequestValidator[0]
Token request validation success, {
"ClientId": "sdgfsdsgsdg",
"ClientName": "Swagger UI",
"GrantType": "password",
"Scopes": "api",
"AuthorizationCode": "********",
"RefreshToken": "********",
"UserName": "sample",
"Raw": {
"grant_type": "password",
"username": "sample",
"password": "REDACTED"
}
}
fail: Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler[3]
Exception occurred while processing message.
System.InvalidOperationException: IDX20803: Unable to obtain configuration from: 'http://*:8080/.well-known/openid-configuration'.
---> System.IO.IOException: IDX20804: Unable to retrieve document from: 'http://*:8080/.well-known/openid-configuration'.
---> System.UriFormatException: Invalid URI: The hostname could not be parsed.
at System.Uri.CreateThis(String uri, Boolean dontEscape, UriKind uriKind)
at System.Uri..ctor(String uriString, UriKind uriKind)
at Microsoft.IdentityModel.Protocols.HttpDocumentRetriever.GetDocumentAsync(String address, CancellationToken cancel)
--- End of inner exception stack trace ---
at Microsoft.IdentityModel.Protocols.HttpDocumentRetriever.GetDocumentAsync(String address, CancellationToken cancel)
at Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectConfigurationRetriever.GetAsync(String address, IDocumentRetriever retriever, CancellationToken cancel)
at Microsoft.IdentityModel.Protocols.ConfigurationManager`1.GetConfigurationAsync(CancellationToken cancel)
--- End of inner exception stack trace ---
at Microsoft.IdentityModel.Protocols.ConfigurationManager`1.GetConfigurationAsync(CancellationToken cancel)
at Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler.HandleAuthenticateAsync()
fail: IdentityServer4.AccessTokenValidation.IdentityServerAuthenticationHandler[0]
IDX20803: Unable to obtain configuration from: 'http://*:8080/.well-known/openid-configuration'.
System.InvalidOperationException: IDX20803: Unable to obtain configuration from: 'http://*:8080/.well-known/openid-configuration'.
---> System.IO.IOException: IDX20804: Unable to retrieve document from: 'http://*:8080/.well-known/openid-configuration'.
---> System.UriFormatException: Invalid URI: The hostname could not be parsed.
at System.Uri.CreateThis(String uri, Boolean dontEscape, UriKind uriKind)
at System.Uri..ctor(String uriString, UriKind uriKind)
at Microsoft.IdentityModel.Protocols.HttpDocumentRetriever.GetDocumentAsync(String address, CancellationToken cancel)
--- End of inner exception stack trace ---
at Microsoft.IdentityModel.Protocols.HttpDocumentRetriever.GetDocumentAsync(String address, CancellationToken cancel)
at Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectConfigurationRetriever.GetAsync(String address, IDocumentRetriever retriever, CancellationToken cancel)
at Microsoft.IdentityModel.Protocols.ConfigurationManager`1.GetConfigurationAsync(CancellationToken cancel)
--- End of inner exception stack trace ---
at Microsoft.IdentityModel.Protocols.ConfigurationManager`1.GetConfigurationAsync(CancellationToken cancel)
at Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler.HandleAuthenticateAsync()
at Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler.HandleAuthenticateAsync()
at Microsoft.AspNetCore.Authentication.AuthenticationHandler`1.AuthenticateAsync()
at Microsoft.AspNetCore.Authentication.AuthenticationService.AuthenticateAsync(HttpContext context, String scheme)
at IdentityServer4.AccessTokenValidation.IdentityServerAuthenticationHandler.HandleAuthenticateAsync()
info: IdentityServer4.AccessTokenValidation.IdentityServerAuthenticationHandler[7]
Bearer was not authenticated. Failure message: IDX20803: Unable to obtain configuration from: 'http://*:8080/.well-known/openid-configuration'.
info: IdentityServer4.AccessTokenValidation.IdentityServerAuthenticationHandler[12]
AuthenticationScheme: Bearer was challenged.
-
ASP.NET using return RedirectToAction(" ", " ") how to use this to redirect to a cshtml
I can not find a useable tutorial that explains how to redirect using REdirectToAction. can someone share a link that that explains ALL the steps needed to use this? I think I am having a hard time understanding how the parameters are given can find an HTML file with a model in the parameter? or is it a controller? I am very lost on how they communicate. please someone if you can help.
-
How to display data in a reusable Table component in Blazor
I'm trying to create a reusable MasterTable component in Blazor.
So far, I've defined the MasterTable as
@using AntDesign @using MyNamespace.Blazor.ViewModels @typeparam TItem <Table TItem="TItem" DataSource="@Data"> @{ foreach (var col in Columns) { <Column Title="@col.Label" @bind-Field="@col.Key" /> } } </Table> @code { private List<TItem> _data; [Parameter] public List<TItem> Data { get => _data; set => _data = value ?? new List<TItem>(); } [Parameter] public TableColumnViewModel[] Columns { get; set; } }
where TableColumnViewModel is defined simply as
public class TableColumnViewModel { public string Key { get; set; } public string Label { get; set; } }
I would like to create an instance of the MasterTable in a page for Daily Tasks but so far I'm only able to get it to display like this:
My attempt to implement MasterTable is as follows:
@page "/Tasks/Daily"; @using MyNamespace.Blazor.Services; @using MyNamespace.Blazor.ViewModels; @using MyNamespace.Api.Client.Model; @inject ITasksService _tasksService; <h1>Daily Tasks</h1> <MasterTable TItem="TaskStatus" Data="_tasks" Columns="cols"> </MasterTable> @code { private List<TaskStatus> _tasks = new List<TaskStatus>(); protected override async Task OnInitializedAsync() { _tasks = await _tasksService.GetTaskStatusAsync(); } TableColumnViewModel[] cols = { new TableColumnViewModel { Key = "id", Label = "ID" }, new TableColumnViewModel { Key = "description", Label = "ID" }, new c { Key = "type", Label = "Type" } }; }
With TaskStatus defined as
public class TaskStatus { public TaskStatus(int taskStatusId = default(int), string statusDescription = default(string)) { this.TaskStatusId = taskStatusId; this.StatusDescription = statusDescription; } public int TaskStatusId { get; set; } public string StatusDescription { get; set; } }
What do I need to do to get the MasterTable template to display the list of TaskStatus objects instead of the keys from TableColumnViewModel?
To be clear - instead of just using the component without wrapping it, the issue is that I want to isolate the CSS in the context of the 3rd party component, so that only the necessary CSS is loaded.
-
Blazor - app.UseIdentityServer(); with .pfx key file - Unexpected character encountered while parsing number
I have created a new Blazor WebAssembly App with Individual User Accounts, Store user accounts in-app and ASP.NET Core hosted in .NET 5. When deploying my app to Azure App Service I get the following error:
Object reference not set to an instance of an object.at Microsoft.Extensions.DependencyInjection.IdentityServerBuilderConfigurationExtensions
Reading these links I have to provide my own certificate in production for IdentityServer:
Blazor Web Assembly App .Net Core Hosted: publish runtime error
https://stackoverflow.com/a/56904000/3850405
I then created a
.pfx
file like this and I have verified that it works and my password is correct.https://stackoverflow.com/a/48790088/3850405
I then placed the
.pfx
file in myServer
projects root folder and markedCopy to Output Directory
asCopy Always
.I then updated
appsettings.json
to look like this:"IdentityServer": { "Clients": { "BlazorTest.Client": { "Profile": "IdentityServerSPA" } }, "Key": { "Type": "File", "FilePath": "localhost.pfx", "Password": "MySercurePassword123?" } },
Now the project does not work neither locally or on Azure. It fails on
app.UseIdentityServer();
inStartup.cs
with the following error:Newtonsoft.Json.JsonReaderException: 'Unexpected character encountered while parsing number: �. Path '', line 1, position 1.'
According to Microsoft docs my certificate should be valid:
A production certificate to use for signing tokens.
- There are no specific requirements for this certificate; it can be a self-signed certificate or a certificate provisioned through a CA authority.
- It can be generated through standard tools like PowerShell or OpenSSL.
- It can be installed into the certificate store on the target machines or deployed as a .pfx file with a strong password.
If I load the key like this it works:
"Key": { "Type": "Store", "StoreName": "My", "StoreLocation": "CurrentUser", "Name": "CN=blazortest" }
-
Is there some how to navigate to a page and pass parameters without use the address bar in Blazor?
This is present in many modern SPA libraries/frameworks...
I will supply an example using React (But it could be Angular or Vue), you can do something like...
this.props.router.push({ pathname: '/login-successfully', state: { userId: 'john', name: 'John Doe } })
and then on the initialization of the "other-page" you will have:
const {state} = useLocation(); const { userId, name } = state;
and you can render things like
<p>Welcome Back, {name}!</p>
Such feature is very useful in many scenarios, but by reading the documentation of routing in Blazor at https://docs.microsoft.com/en-us/aspnet/core/blazor/fundamentals/routing?view=aspnetcore-5.0 I cannot find anything. The NavigationManager just have those parameters:
public void NavigateTo (string uri, bool forceLoad = false);
Is there some equivalent approach that I can use ? I know a workaround by creating a singleton class, store the data over there and display on the login-successfully page, but I really hope to find something better as solution.
-
how to keep alive my Blazor Server side app IIS 8.5
I need to keep my blazor server side app alive all time.
I tried to set my iis 8.5 start mode setting to alwaysrunning and idle to 0 but still shutting down the app and caught stopping signal... after between 23h to 29h...
what i have to do to keep it alive, which setting i missed? Do i have to add code on web.config?
-
How to turn a single page of a large web site into a stand-alone PWA with Blazor
I have a web site with thousands of pages and more being added daily due to the fact that users can add a page for their own product and associated information. In addition to storing the data the user enters when creating a new page in a database to be used when serving that page, I want to be able to create a Blazor PWA with just that one page so the user can install it on their device(s) and see updates to comments, etc. as the changes occur. My questions are these:
Can I programmatically create a Blazor PWA and then send the user the link so they can install just that one page on their device?
Can a Blazor server app contain Blazor client pages?
-
Frequent page updates in blazor server application
In a blazor server application, is it okay to send events and call
StateHasChanged
very often, e.g., 500 times per second?One of my pages needs to react to an external event and then update its state accordingly. I found the following solution:
- Create a service that detects the external event and invokes a C# event.
- Inject the service into the razor page.
- In the page, connect to the event and call
InvokeAsync(() => StateHasChanged())
in the handler.
This already works correctly. However, the event may occur very often, e.g., 500 times per second, and I worry about the performance of client and server. Unfortunately, I dont understand which part happens on the server, which part happens on the client, and which data is sent between them.
- Are the events actually sent 500 times per second from the server to the client? I think this would consume a lot of bandwidth.
- Does the client actually render the page after each call to
StateHasChanged
? I think this would impose a high CPU load on the client.