Wednesday, September 27, 2023

Troubleshooting Deploying Blazor to a Linux App Service in Azure

It all started one day when I decided to try and deploy the Bed Brigade National Website (which is a Blazor Server application) to Azure using Github actions.  

The github repo is located here:  https://github.com/GregFinzer/BedBrigadeNational

Thank God for Patrick God and Tim Corey who have excellent tutorials on YouTube.  Here are the videos that I followed when deploying to Azure:

Create Web App in Azure: https://www.youtube.com/watch?v=NiBEk8QepP4

Deploy Blazor with Github actions:  https://www.youtube.com/watch?v=wybpWMrpuZk

Updating the Connection String in Blazor:  https://www.youtube.com/watch?v=lSCjtrNkT38

Deployment is always difficult and deploying to Azure has its share of pain.  Only the first exception was obvious.    

Could not find part of the path

I had volunteers working on the website and they were using non-standard path combination.  In other words, they were making a windows platform specific path like this:

string directory = appRoot + "\\" + folder + "\\" + filename;

The platform agnostic way to do this so it works under Linux:

string directory = Path.Combine(appRoot, folder, filename)


SQL Server Transient Failure

If you are using Basic B1 and a low tier for SQL Server, get ready for a lot of retries.  This is even if you have caching enabled in your application.  Here is my previous post on caching:  https://sixfootcoder.blogspot.com/2018/09/using-caching-in-net-framework.html


You will get this error message:

An exception has been raised that is likely due to a transient failure. Consider enabling transient error resiliency by adding 'EnableRetryOnFailure' to the 'UseSqlServer' call.  

In order to fix this, you have to add a line to your context factory with EnableRetryOnFailure.
  
builder.Services.AddDbContextFactory<DataContext>(options =>
{
    options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection"), sqlBuilder =>
    {
        sqlBuilder.EnableRetryOnFailure(5, TimeSpan.FromSeconds(10), null);
    });
    options.UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking);
    options.UseApplicationServiceProvider(_svcProvider);
});


Unable to resolve service for type IResponseCompressionProvider

Blazor Server does not support Response Compression.  You might be seeing this exception:

Unable to resolve service for type 'Microsoft.AspNetCore.ResponseCompression.IResponseCompressionProvider' while attempting to activate 

If you have this line in your program.cs, remove it as that is causing the error:

app.UseResponseCompression();

Could not load assembly DependencyModel

There is a known issue with Serilog and Azure.  You may be seeing this exception:

Unhandled exception. System.IO.FileNotFoundException: Could not load file or assembly 'Microsoft.Extensions.DependencyModel

There are two fixes that you have to make for this:

Add a reference to these NuGet packages in your client project:
Microsoft.Extensions.DependencyInjection
Microsoft.Extensions.DependencyModel

If you have a tests project, go to the properties of the project.  Under Application and then Packaging, uncheck:  Allow publishing outside Visual Studio, such as "dotnet publish"

Connection Timeout Expired

You might be seeing this error:  

Microsoft.Data.SqlClient.SqlException (0x80131904): Connection Timeout Expired.  The timeout period elapsed during the post-login phase.  The connection could have timed out while waiting for server to complete the login process and respond; Or it could have timed out while attempting to create multiple active connections.  The duration spent while attempting to connect to this server was - [Pre-Login] initialization=162; handshake=279; [Login] initialization=0; authentication=1; [Post-Login] complete=29565; 

This was the worst error to deal with.  I can't believe that this is a default Azure option for SQL Server but it is.  SQL Server has an Auto Pause feature that if it is not used then it shuts down.  Supposedly it should come back up when accessed again but it does not.  There is a defect.  It shuts down and stays down.  

To correct this issue, click on the SQL Service then SQL Databases, then the name of your database and finally Compute + Storage.  Uncheck Enable auto-pause.




The other option you should do is to enable Always On for your App Service.  Click on your App Service, then Configuration, then General settings, and then Always On.



No comments:

Post a Comment