I created a simple Blazor Server Application:
The class "UserSettings.cs" is injected in the components.
public class UserSettings
{
public Guid Id{ get; } = Guid.NewGuid();
}
services.AddScoped<UserSettings>();
I display the Id inside the UserSetting Service in different Components.
After switching the component, the Id stays the same, but when i refresh the page, it changes.
Why does the Service initialized again when refreshing the page?
Your service is scoped to the circuit connection...When you refresh the page, a new circuit object is created. You may use the AddSingleton instead, but in that case all your users may see the same ID.
Why not create the Id when your App is rendered for the first time, and save it in a session storage or local storage for use ?
Related
So I've been playing with Blazor and I have the following:
I've created a Singleton Service that set's a value for the version of the program that I can access in the rest of the software
I've created a web service call to get data from a separate API which can be used to populate on a razor page.
However, I've been trying to figure out how to set something on startup of the app that can check an API for a value and set a variable to that value that can be used for the life of the app running.
I figured I could create a Singleton service that calls the API but I'm having a difficult time figuring that out. The value I want to store is simple, just a string.
In program.cs:
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.Services.AddSingleton<ISomeService, SomeService>();
Where ISomeService is an interface, and SomeService is a class that implements your interface. It contains the functionality that gets your data from the desired API.
In your razor page code:
[Inject] ISomeService MyService { get; set; }
To retrieve the data:
string value = MyService.GetValue();
Which is a method you have defined in ISomeService.cs and implemented in Service.cs.
I have a Blazor server side app. All the user specific variables I have defined in a scoped service. (TagService). With my app the user can connect to a production machine and read their PLC and CNC data. If the user disconnects from the current machine, I want that all the variables that are defined in the scoped service are initialized to their defined default values (Like 0 or "")
I do that normally in a classic way shown in the code below.
When the user clicks the disconnect button I call a function in the scoped service where I set all the user specific variables to their default values one by one. I have few hundred variables and I loose more and more the overview in this way.
Is there an easier way, so that I can reinitialize all the variables in a scoped service to their initial values with just one command instead of setting back their values one by one to their default values?
Razor page code
#inject TagService TagService
<button #onclick="Disconnect">Disconnect</button>
private void Disconnect()
{
TagService.Delete_UserTags();
}
Scoped Service (TagService)
public class TagService
{
public int Tag1=0;
public int Tag2=0;
public int Tag3=1;
public string Tag4="";
// few hundred Tags
public void Delete_UserTags()
{
Tag1=0;
Tag2=0;
Tag3=0;
Tag4="";
//setting all the few hundred tags to their initial value
}
}
My singleton object does not keep its state when loading a new page in blazor.
I have this interface:
public interface IPreLaunchSession
{
bool IsPreLaunchAuthenticated { get; set; }
}
The class for this interface
public class PreLaunchSession : IPreLaunchSession
{
public bool IsPreLaunchAuthenticated { get; set; }
public PreLaunchSession()
{
}
}
I register it as a singleton
builder.Services.AddSingleton<IPreLaunchSession,PreLaunchSession>();
Then inject it into the page
#inject Services.IPreLaunchSession PreLaunchSession
In these pages where its injected, I test for the bool variable as well as set it.
In another section of code, I redirect using NavigationManager. Something like this:
Navigation.NavigateTo("/MyOtherPath");
This seems to work for a while but then a <NavLink/> is used to go to another page and as soon as this happens then the PreLaunchSession object seems to be recreated and the bool variable in it is reset to default (which is false)
Any help here would be great in understanding why a singleton object gets recreated with navigation happening.
Have a look at how to persist value in a singleton state container in blazor web assembly on page reload
When refreshing the app (F5 etc) the app is essentially turned off and turned on again.
This would cause the whole app to restart and all memory of persisted singleton objects would be lost.
I ended up using localstorage to persist between full refreshes or tab changes.
I'm new to web application in asp.net mvc 5. I'm curious about how static classes behaves in web application. I'd like to know how my program will behave.
Let's say I have CurrentUser static class which stores logged user id.
public static class CurrentUser{
public static int UserId {get; set;}
}
Which is set whenerever user is logging in.
My app is in external server.
So what will happen if:
User A log in -> userId is set to 1, then User B log in (they access to from differentlcoations) so user Id is set to 2. When User A would like to perform action which need to check his Id, will it be 1 or 2?
I checked one scenario where 2 differentpersons log in from one pc at the same time (different tabs) and I know that User Id will be 2 for both of them (when User B logged in as second to the app). How to resolve this?
I've already read: Static classes in web applications.
I know that my solution may be error prone because every one has access to that class but I don't know if static classes in web app aren't store per user (thread?)?
If you store current user in session storage it will be better than static class. Because there is one copy of static class and fields and for every user login the last login is kept.
Here's the deal: I have a site where multiple people will be sharing the same account and should each be able to be on a page that uploads files and keeps a list of the files they've uploaded that session. The controller for the file uploading page looks like
public class FileUploadController : Controller
{
// ...
private List<ThreePartKey> uploadedFiles = new List<ThreePartKey> ();
public ActionResult Index ( )
{
// ...
}
[HttpPost]
public ActionResult Index (HttpPostedFileBase file)
{
// ...
if (!errorOccured)
{
uploadedFiles.Add(new ThreePartKey { orgname = selectedOrgName, catname = selectedCatName, filename = fileNameNoExtension, fullfilepath = newFileUrlPathAndName });
}
// ...
}
and the problem is that uploadedFiles keeps getting re-initialized whenever [HttpPost] public ActionResult Index (HttpPostedFileBase file) is called, meaning the user's list of uploaded files only shows the last uploaded one. So I instead tried
private static List<ThreePartKey> uploadedFiles = new List<ThreePartKey> ();
and that screwed up everything because all the signed-in users are sharing the same list.
Is there any easy way to do what I'm trying to do?
Controllers are instantiated and destroyed on every request. If you want to persist information in a webserver it is strongly advised to use a permanent backing store such as a database.
You can use static state in ASP.NET applications (WebForms, MVC, OWIN, etc) however this is only recommended for caching for performance. It cannot be relied upon because static state is only local to the current AppDomain in the current Application Pool (w3wp.exe instance) - if your website is run in multiple pools or appdomains, or if your application is restarted (or killed due to inactivity) then the stored state is lost.
On option is to provide a 'session' code/id with each request. When user first connects to your site, they are given a session-code (I use 'code' to indicate it has nothing to do with what we would normally call 'session').
Every link has that session-code as part of the url and every post includes the session-code. Then your upload cache can be:
private static ILookup<int, ThreePartKey> uploadedFiles;
(or dictionary if you prefer)
private static IDictionary<int, IList<ThreePartKey>> uploadedFiles;
Depends on the size of the rest of your site if this is workable or not - in most cases probably not as described... but could be managed, eg use the IP address as the 'code' or if you're using AnglurJS or single page application.
As pointed out, any static/singleton cache will still be lost if the app pool is reset, eg via the inactivity timeout setting in IIS.
Another option is to persist the files in subfolders based on the user's IP address.
You've only stipulated that they all use the same login, not how the files are stored etc, so maybe this would work for you.