Bind Collections using IDbContextFactory
I am about to create a blazor application with ef core. I read the Microsoft recommentation about how to Setup EF Core DbContextFactory
Until now i used in my Razor-Components bindindings to the DbSet like
<select @bind-value="dbContext.People" />
since I read the Article I'm a little confused of how to used it now, because they use the dbcontext inside of a using-Statement.
because of the using statement i cant directly bind a dbset anymore???
@inject IDbContextFactory<DatabaseContext> DbFactory
<select @bind-value="dbContext.People" />
@code
{
DatabaseContext dbContext;
protected override Task OnInitializedAsync()
{
using var dbContext = DbFactory.CreateDbContext();
}
}
Whats your suggestion for that?
If i use
<input @bind-value="People" />
@code
{
ICollection<Person> People;
protected override Task OnInitializedAsync()
{
using var dbContext = DbFactory.CreateDbContext();
People = dbContext.People;
}
}
nothing will be displayed. The Debugger tells me:
Cannot access a disposed context instance. A common cause of this error is disposing a context instance that was resolved from dependency injection and then later trying to use the same context instance elsewhere in your application. This may occur if you are calling 'Dispose' on the context instance, or wrapping it in a using statement. If you are using dependency injection, you should let the dependency injection container take care of disposing context instances. Object name: 'DatabaseContext'.
1 answer
-
answered 2021-01-19 09:35
Henk Holterman
//DatabaseContext dbContext; ICollection<Person> persons = null; protected override async Task OnInitializedAsync() { using var dbContext = DbFactory.CreateDbContext(); persons = await dbContext.Person.ToArrayAsync(); }
and make sure to use
@if (persons != null) { ... }
in the markup.
See also questions close to this topic
-
Convert CSV file data from any language to English in C#
I would like to convert CSV file data from multi languages such as Spanish, Russian, European etc to English language in C# program.
Convert all characters like Ó, É to English characters.
Thanks.
-
I get an error when solving this problem, How can I fix?
I am trying to solve the Climbstairs problem but in reverse, where I want to know the number of steps I have to take to go down.
I can go down 1, 2, 3 or 4 steps at the same time. That is, if I am at step i, I can go down to step i - a for any of the values 1, 2, 3 or 4 of a.
I have the following code but I don't know what happens:
I got this error: System.IndexOutOfRangeException in this line:
steps[i] += steps[i - a];
Why I have this error?
public static int DownStairs(int n) { int[] steps = new int[n + 1]; steps[n] = 1; steps[n - 1] = 1; for (int i = n-2; i>=0; i--) { for(int a = 1; a<=4; a++) { steps[i] += steps[i - a]; } } return steps[n]; } static void Main(string[] args) { int n = 5; DownStairs(n); }
-
How to delete multiple blank lines in a WPF DataGrid imported from an Excel file
I have a WPF DataGrid which I fill with imported data from an Excel file (*. Xlsx) through a class, the problem is that multiple blank lines are added to the end of the DataGrid that I don't see how to delete. I attach my code.
<DataGrid Name="dgvMuros" Height="210" Margin="8" VerticalAlignment="Top" Padding="5,6" ColumnWidth="50" IsReadOnly="False" AlternatingRowBackground="Azure" GridLinesVisibility="All" HeadersVisibility="Column" Loaded="dgvMuros_Loaded" CellEditEnding="DataGrid_CellEditEnding" ItemsSource="{Binding Data}" HorizontalGridLinesBrush="LightGray" VerticalGridLinesBrush="LightGray" > </DataGrid>
With this method I import the data from the Excel file.
public void ImportarMuros() { ExcelData dataFronExcel = new ExcelData(); this.dgvMuros.DataContext = dataFronExcel; txtTotMuros.Text = dataFronExcel.numMuros.ToString(); cmdAgregarMuros.IsEnabled = false; cmdBorrarMuros.IsEnabled = false; cmdImportar.IsEnabled = false; } public class ExcelData { public int numMuros { get; set; } public DataView Data { get { Excel.Application excelApp = new Excel.Application(); Excel.Workbook workbook; Excel.Worksheet worksheet; Excel.Range range; workbook = excelApp.Workbooks.Open(Environment.CurrentDirectory + "\\MurosEjemplo.xlsx"); worksheet = (Excel.Worksheet)workbook.Sheets["DatMuros"]; int column = 0; int row = 0; range = worksheet.UsedRange; DataTable dt = new DataTable(); dt.Columns.Add("Muro"); dt.Columns.Add("Long"); dt.Columns.Add("Esp"); dt.Columns.Add("X(m)"); dt.Columns.Add("Y(m)"); dt.Columns.Add("Dir"); for (row = 2; row < range.Rows.Count; row++) { DataRow dr = dt.NewRow(); for (column = 1; column <= range.Columns.Count; column++) { dr[column - 1] = Convert.ToString((range.Cells[row, column] as Excel.Range).Value); } dt.Rows.Add(dr); dt.AcceptChanges(); numMuros = dt.Rows.Count; } workbook.Close(true, Missing.Value, Missing.Value); excelApp.Quit(); return dt.DefaultView; } } }
-
InvalidOperationException when attempting to run an asynchronous Entity Framework Core query in IClaimsTransformation implementation
I have an
IClaimsTransformation
implementation as follows:public class RolesClaimsTransformer : IClaimsTransformation { private readonly DB_TH_Custom_Apps_SQLContext ctx; public RolesClaimsTransformer(DB_TH_Custom_Apps_SQLContext ctx) { this.ctx = ctx; } public async Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal) { // TODO: If I drop the addition of the claim to the original, will I need to change this? if (principal.Identity.IsAuthenticated && !principal.Claims.Any(c => c.Type == ClaimTypes.Role)) { // It's preferred to do this against a "new" object rather than the original one var clone = principal.Clone(); clone.AddIdentities(from ur in ctx.UserRoles where ur.User.Ntid == principal.Identity.Name select new ClaimsIdentity(new[] { new Claim(ClaimTypes.Role, ur.Role.RoleName) })); return clone; } else return principal; } }
This works just fine; however, performance profiling shows that this method is a "hot path," so I was trying to optimize it. As part of the overall optimization, I thought that I'd see if making the database query call asynchronous would improve my web application's responsiveness. (Obviously, I'm aware of the overhead that the
async
"compiler magic" adds, so I was specifically not expecting that simply making thisasync
would make this no longer be a "hot path"; however, I was hoping for an overall performance and scalability gain from it for my app as a whole).When I try to do something like:
var roles = ctx.UserRoles.ToListAsync();
I get the following exception:
InvalidOperationException: The source IQueryable doesn't implement IDbAsyncEnumerable<Data_Layer.UserRoles>. Only sources that implement IDbAsyncEnumerable can be used for Entity Framework asynchronous operations. For more details see http://go.microsoft.com/fwlink/?LinkId=287068.
The linked article is not helpful because it refers to in-memory databases for testing, which is not what I'm doing here - I'm calling the "real" SQL Server 2016 database.
I use asynchronous queries involving
.ToListAsync()
numerous other places in my code base; it's only in this particular method that this occurs.This does not appear to be related to the order of initialization in my
Startup.cs
file because, when I try the following code, the exception still occurs every time (not just on the "first" call):try { clone.AddIdentities(await (from ur in ctx.UserRoles where ur.User.Ntid == principal.Identity.Name select new ClaimsIdentity(new[] { new Claim(ClaimTypes.Role, ur.Role.RoleName) })).ToListAsync()); } catch (Exception) { clone.AddIdentities(from ur in ctx.UserRoles where ur.User.Ntid == principal.Identity.Name select new ClaimsIdentity(new[] { new Claim(ClaimTypes.Role, ur.Role.RoleName) })); }
In the off chance that I'm wrong about that last point, here's the relevant portion of my
ConfigureServices
method:public void ConfigureServices(IServiceCollection services) { services.AddDbContext<DB_TH_Custom_Apps_SQLContext>(); services.AddAuthentication(IISDefaults.AuthenticationScheme); services.AddTransient<IClaimsTransformation, RolesClaimsTransformer>(); // Various other unrelated registrations services.AddAuthorization(); services.AddControllersWithViews(); }
What am I missing here? Why does this problem appear only in my
IClaimsTransformation
implementation and nowhere else? -
What is the correct way to do many to many entity relation insert?
I am using .net5 and EntityFrameworkCore 5.
I have a many to many relationship between Questions and Categories.
I am using Code first generation.
public class Question { public int Id { get; set; } public string Title { get; set; } public ICollection<Category> Categories { get; set; } }
public class Category { public int Id { get; set; } public string Name { get; set; } public ICollection<Question> Questions { get; set; } }
I want to know how to add a Question with Categories.
I tried this :
[HttpPost] public async Task<ActionResult<Question>> PostQuestion(Question question) { question.Categories.Add(new Category() { Id = 1 }); _context.Questions.Add(question); await _context.SaveChangesAsync(); return CreatedAtAction("GetQuestion", new { id = question.Id }, question); }
And I have a Category with the Id : 1 in my database.
However I get this exception
SqlException: Cannot insert explicit value for identity column in table 'Categories' when IDENTITY_INSERT is set to OFF.
What is the correct way to do many to many entity relation insert ?
-
EF Core in memory store lists
I'm pretty new to the whole EF Core in memory database concept, so I'm probably missing a few important things here, but I need this figured out sooner or later.
What I'm trying to achieve is Add an object which contains lists of other objects to database. While the primitive data types are stored correctly, the lists seem to be always null.
public class Race { public int RaceId { get; set; } public int Year { get; set; } public List<Vehicle> AllRunningVehicles { get; set; } public List<Vehicle> AllRepairingVehicles { get; set; } public List<Vehicle> AllDeadVehicles { get; set; } public Race() { //AllRunningVehicles = new List<Vehicle>(); //AllRepairingVehicles = new List<Vehicle>(); //AllDeadVehicles = new List<Vehicle>(); } }
And here is the controller
public class RaceController : Controller { private readonly RaceContext _raceContext; public RaceController(RaceContext Rcontext) { _raceContext = Rcontext; } [HttpPost] [Route("[controller]/[action]")] public async Task<ActionResult<Race>> PostRaceItem(int year) { Race raceItem = new Race(); raceItem.Year = year; raceItem.AllRunningVehicles = new List<Vehicle>(); raceItem.AllRepairingVehicles = new List<Vehicle>(); raceItem.AllDeadVehicles = new List<Vehicle>(); await _raceContext.RaceItems.AddAsync(raceItem); await _raceContext.SaveChangesAsync(); return raceItem; } [HttpGet] [Route("[controller]/[action]")] public async Task<ActionResult<Race>> GetRaceItem(int raceID) { var raceItem = await _raceContext.RaceItems.FindAsync(raceID); if (raceItem == null) { return NotFound(); } return raceItem; } }
I've tried creating lists in Ctor, but that way they are always empty, the data stored in them is always wiped out, which I don't want to. I will include Context and Startup classes, just in case they need some additional configuration which I'm not aware of.
public class RaceContext : DbContext { public RaceContext(DbContextOptions<RaceContext> options) : base(options) { } public DbSet<Race> RaceItems { get; set; } }
And the Startup
public class Startup { public Startup(IConfiguration configuration) { Configuration = configuration; } public IConfiguration Configuration { get; } // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.AddDbContext<RaceContext>(opt => opt.UseInMemoryDatabase("RaceList")); services.AddControllers(); services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new OpenApiInfo { Title = "TEST", Version = "v1" }); }); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); app.UseSwagger(); app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "TEST v1")); } app.UseHttpsRedirection(); app.UseRouting(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); } }
-
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.