-3

8/29/23: I will apply the suggestions mentioned in the comments below.

  1. Added Using Statement where I omitted it.
  2. Removing the While loop and using another page or project to trigger the call in a manner simulating the page being hit repeatedly.
  3. I will look at migrating to a Code First approach, but I have always built the DB first as that is what I am used to doing.

That said...

Please help me understand why this case keeps getting closed as I have a very real problem that is extremely difficult to solve. When I post the details as I understand them my case keeps getting closed.

I have no debug information. That is the crux of the issue. Normal debugging information in the form of exceptions or log entries are not being generated. If they were, I would use them to find the cause, but the are not.

So what do I need to do to get this issue open and available for ideas?

I am doing the best I can yet it keeps getting closed. Please help me get it solved, as this is killing our development plans.

Code is now at end of the post.

My question is:

How do I debug an issue that does not produce any debugging information, does not throw exceptions and simply produces a 'service unavailable' message when it fails?

No information is logged no matter what I do. I have a couple of other posts on this where I was told to build a Minimal Reproduction Project, that is what this post is about. I have that, but do not see how to attach it to the post. It will reproduce this issue and will crash without any logging data or exceptions thrown.

Background:

I have been fighting with Blazor and EF for months now trying to get it to work reliably and no matter what I do it crashes after repeated page accesses.

I have a DB and a minimal repro that will crash after the page is refreshed roughly 250 - 300 times. This is greatly reduced if the DB has more data and more complexity, in my actual app it will fail after less than 50 hits, sometimes around 20.

I have eliminated all known issues like misuses of dependency injection, I have simplified the DB down to a single table with 2 fields and one row, I have scoured the internet and taken all manner of feedback to no avail. It still crashes without any debugging information.

I am desperate for a solution. I am many months behind schedule as a result of this, and I have invested a great deal of time in learning Blazor/EF so there will be a lot of 'sunk cost' if I have to bail and find some other framework.

Please advise.

Program.cs:

    using BlazorDbTest.Data;
using BlazorDbTest.Services;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Web;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;

var builder = WebApplication.CreateBuilder(args);
var connectionString = builder.Configuration.GetConnectionString("development");

builder.Services.AddDbContextFactory<BttestContext>(options => options.UseSqlServer(connectionString));

builder.Services.AddDatabaseDeveloperPageExceptionFilter();

// Add services to the container.
builder.Services.AddRazorPages();
builder.Services.AddServerSideBlazor();
builder.Services.AddSingleton<WeatherForecastService>();
builder.Services.AddHttpContextAccessor();
builder.Services.AddTransient<AccountUtilitiesService>();
var app = builder.Build();

// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
    app.UseHsts();
}

app.UseHttpsRedirection();

app.UseStaticFiles();

app.UseRouting();

app.MapBlazorHub();
app.MapFallbackToPage("/_Host");
app.MapControllers();

app.Run();

Controller:

    using BlazorDbTest.Services;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;

namespace BlazorDbTest.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class GetAccountEmailController : ControllerBase
    {
        private readonly AccountUtilitiesService _accountUtilitiesService;
        private static int counter = 0;
        public GetAccountEmailController(AccountUtilitiesService accountUtilitiesService)
        {
            _accountUtilitiesService = accountUtilitiesService;
        }

        [HttpGet]
        public IActionResult GetEmail(string AccountID)
        {
            bool stillworking = true;

            string email = string.Empty;

            while(stillworking)  //<<<--- this is here to avoide having to click the Refresh button 250 or so times.  It will crash with or without this loop.
            {
                counter++;
                stillworking = false;
                try
                {
                    email = _accountUtilitiesService.GetAccountEmail(AccountID)+ "\nCount: " + counter;
                    stillworking = true;
                }
                catch (Exception e)
                {
                    email += e.Message;
                }
            }

            if(!stillworking) 
            { 
                email = "Failed after " + counter + " Hits";
            }

            return Ok(email);
        }
    }
}

Service:

    using BlazorDbTest.Data;
using Microsoft.EntityFrameworkCore;

namespace BlazorDbTest.Services
{
    public class AccountUtilitiesService : IDisposable
    {
        private readonly IDbContextFactory<BttestContext> _dbContextFactory;
        public AccountUtilitiesService(IDbContextFactory<BttestContext> dbContextFactory)
        {
            _dbContextFactory = dbContextFactory;
        }

        public string? GetAccountEmail(string accountId)
        {
            string? email = "Account not found";
            

            if (!string.IsNullOrEmpty(accountId))
            {
                int? accountID = int.Parse(accountId);
                using BttestContext bttestContext = _dbContextFactory.CreateDbContext();
                email = bttestContext.Accounts.FirstOrDefault(a=>a.AccountId == accountID)?.Email;
            }
            return email;
        }
        public void Dispose()
        {
            // TODO release managed resources here
        }
    }
}

DB Context:

    using System;
using System.Collections.Generic;
using BlazorDbTest.Models;
using Microsoft.EntityFrameworkCore;

namespace BlazorDbTest.Data;

public partial class BttestContext : DbContext
{   
    public BttestContext()
    {
    }

    public BttestContext(DbContextOptions<BttestContext> options)
        : base(options)
    {
    }

    public virtual DbSet<Account> Accounts { get; set; }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
#warning To protect potentially sensitive information in your connection string, you should move it out of source code. You can avoid scaffolding the connection string by using the Name= syntax to read it from configuration - see https://go.microsoft.com/fwlink/?linkid=2131148. For more guidance on storing connection strings, see http://go.microsoft.com/fwlink/?LinkId=723263.
    {
        var builder = WebApplication.CreateBuilder();

        var connectionString = builder.Configuration.GetConnectionString("development");
        optionsBuilder.UseSqlServer(connectionString);
    }
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.HasDefaultSchema("db_owner");

        OnModelCreatingPartial(modelBuilder);
    }

    partial void OnModelCreatingPartial(ModelBuilder modelBuilder);
}
    

Account.cs:

    using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Microsoft.EntityFrameworkCore;

namespace BlazorDbTest.Models;

[Keyless]
[Table("Accounts", Schema = "dbo")]
public partial class Account
{
    [Column("Account_ID")]
    public int? AccountId { get; set; }

    [Column("Email")]
    public string Email { get; set; }
}

Connection String:

"server=tcp:Geckoserver;Data Source=GECKOSERVER\\SQLBT;Initial Catalog=BTTest; Integrated Security=False; Persist Security Info=True;User ID=BT_Mgr;Password=;Encrypt=False;TrustServerCertificate=True; MultipleActiveResultSets=True" //Integrated Security=True;
  • 2
    If information is important to your question post it in your question; links to off site resources (that honestly look like spam based on the URL) isn't helpful. Code should be included in your question. Take the time to produce a [mre]. Certainly people are *not* going to trust a random zip files from a stranger on the internet. – Thom A Aug 19 '23 at 18:16
  • As I said on your previous question: narrow it down. Ask one question about one *reproducible* issue here. Then maybe later the next question. – Gert Arnold Aug 19 '23 at 18:22
  • @ThomA I looked for a way to include the files, but did not see any, so I linked to them. The files are just what you said I need to provide, but I do not see any way to attach files. – BookTrakker Aug 20 '23 at 18:11
  • 2
    The proper way to include code is using code blocks. Just paste the code, then select it, then press Ctrl-K. Repeat if you have multiple code blocks. – Peter B Aug 20 '23 at 18:20
  • 1
    Attaching the files here would not change the fact that we, as other users, are going to trust a zip file from a random stranger. – Thom A Aug 20 '23 at 18:36
  • 1
    If you want people to look into it and it is really too large then put it in a repo on GitHub. – H H Aug 20 '23 at 20:12
  • Anyone reading this question should be aware there there's a long trail of questions on this topic. Here is the most recent - https://stackoverflow.com/questions/76290079/blazor-server-app-does-not-survive-after-several-accesses-to-the-database-no-s – MrC aka Shaun Curtis Aug 21 '23 at 14:30
  • @BookTrakker- if you have an MRE in a repo that demonstrates the issue then do as HH says. Add it to Github, make it public and add the link here. – MrC aka Shaun Curtis Aug 21 '23 at 14:32
  • @BookTrakker: "I have a minimal repro DB" is worrying. You should have an EF Migration or at least an SQL create script. – H H Aug 21 '23 at 15:20
  • As for linking to a github repo, no that's not the way to go. Stack Overflow questions are supposed to be stand-alone and not dependent of potentially transient links. See also: https://meta.stackoverflow.com/q/359303/861716 – Gert Arnold Aug 21 '23 at 19:57
  • I did put this as a repository on Github, and now I added the code directly here. I just did not think that was the appropriate thing to do, but I guess I was wrong on that. – BookTrakker Aug 24 '23 at 16:38
  • 1
    I don't know what the default timeout limits are but a controller endpoint is not the correct place for that while loop. – H H Aug 24 '23 at 17:48
  • You need a Client (Console app or Blazor) to call this API in a loop. Each call should do 1 query on the controller. – H H Aug 24 '23 at 17:52
  • And you didn't mention the github url. Just in case soemone want to look at it. – H H Aug 24 '23 at 18:02
  • Also, add he `using` in `using BttestContext bttestContext = _dbContextFactory.CreateDbContext();` – H H Aug 24 '23 at 18:25
  • So after many questions and many comments on this question it *finally* turns out you're blowing up your web server by a never-ending `while` loop. I don't see any reason for this loop. What's the idea? – Gert Arnold Aug 24 '23 at 18:50
  • @GertArnold - that while loop is a debug artifact but it shouldn't be at that place. – H H Aug 28 '23 at 08:36
  • The while loop is there to avoid having to click the button repeatedly. It crashes identically without the while loop, so I am not convinced that is a valid issue. In other words, I had a version where you click Refresh over and over roughly 250 or so times, and this while loop eliminated the need. In both cases, it crashes. I do nto see how the while loop can be said to be the cause if it crashes without it. – BookTrakker Aug 29 '23 at 13:37
  • @HH: Thanks! That was a genuine coding error - I know it is needed, but in my editing I must have forgotten it or inadvertently removed it. I am going to try to revise this to break out the While loop bit into another project as was suggested above. It is a bit more work, but I really need this resolved, and if that helps clarify the situation, then by all means it is worth it. And I totally get it, I wondered about this approach, and appreciate the comment about using another project to call this one. – BookTrakker Aug 29 '23 at 13:47
  • You keep a journal here now but nobody will be able to help you. There still is no mre , no repo url and you didn't state if running it on different hardware (esp the Db) makes a difference. – H H Aug 30 '23 at 08:11
  • @HH - I have run it on multiple systems and it fails no matter where it is run. I am doing my best to create a Code First example, but due to this and other factors that are unrelated, I am totally slammed and can only do what I can - I get that impacts how soon anyone can help. I am in the process of converting to a Code First, but I have to learn how to do that first. I got slammed for posting a repo URL, so you confuse me with that part of the comment. – BookTrakker Aug 31 '23 at 13:15
  • It's not std policy but you can drop a url in a comment. – H H Aug 31 '23 at 14:17
  • Clone this and see if you can break it: https://github.com/henk787/BlazorServerDb.git – H H Aug 31 '23 at 16:07
  • And test it with 2+ Browsers concurrently. @BookTrakker. – H H Aug 31 '23 at 16:59

0 Answers0