将含Client、Server、Shared的Blazor WASM + .NET Core API解决方案发布至Azure DevOps的最佳方法及问题求助
Your Solution Setup
You have a solution with three projects:
- Client: Blazor WASM
- Server: .NET Core API integrated with Identity Server
- Shared: Shared code library
Client Project Program.cs
public static async Task Main(string[] args) { var builder = WebAssemblyHostBuilder.CreateDefault(args); builder.RootComponents.Add<App>("#app"); builder.Services.AddHttpClient("TurismoCascais.ServerAPI", client => client.BaseAddress = new Uri(builder.HostEnvironment.BaseAddress)) .AddHttpMessageHandler<BaseAddressAuthorizationMessageHandler>(); // Provides HttpClient instance with access token for server requests builder.Services.AddScoped(sp => sp.GetRequiredService<IHttpClientFactory>().CreateClient("TurismoCascais.ServerAPI")); builder.Services.AddApiAuthorization(); await builder.Build().RunAsync(); }
Server Project Startup.cs
public void ConfigureServices(IServiceCollection services) { services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer( Configuration.GetConnectionString("DefaultConnection"))); services.AddDatabaseDeveloperPageExceptionFilter(); services.AddDefaultIdentity<ApplicationUserModelDB>(options => options.SignIn.RequireConfirmedAccount = true) .AddEntityFrameworkStores<ApplicationDbContext>(); services.AddIdentityServer() .AddApiAuthorization<ApplicationUserModelDB, ApplicationDbContext>(); services.AddAuthentication() .AddIdentityServerJwt(); services.AddControllersWithViews(); services.AddRazorPages(); services.AddAutoMapper(typeof(Startup)); ... } // Runtime calls this method to configure the HTTP request pipeline public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); app.UseMigrationsEndPoint(); app.UseWebAssemblyDebugging(); } else { app.UseExceptionHandler("/Error"); // Default HSTS value is 30 days, adjust for production as needed app.UseHsts(); } app.UseHttpsRedirection(); app.UseBlazorFrameworkFiles(); app.UseStaticFiles(); app.UseRouting(); app.UseIdentityServer(); app.UseAuthentication(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapRazorPages(); endpoints.MapControllers(); endpoints.MapFallbackToFile("index.html"); }); }
Answers to Your Questions
1. Best Way to Publish to Azure DevOps & Deployment Order
The optimal approach depends on whether you want to host the Client and Server together or separately:
Option 1: Host Client + Server Together in Azure App Service
This is the simplest setup—your Server already includes UseBlazorFrameworkFiles() and MapFallbackToFile("index.html"), which embeds the Blazor WASM client in the Server's publish output. For this:
- You don’t need separate publish steps for Client and Server. A single publish of the Server project deploys both components.
- In Azure DevOps, use a YAML pipeline with these core steps:
- Restore dependencies for the entire solution
- Build the solution in Release configuration
- Publish the Server project to a zip archive
- Deploy the zip to your Azure Windows App Service
Option 2: Host Client in Static Web Apps, Server in App Service
If you want separate hosting (for better static content scalability):
- Deployment order matters: Publish the Server first, then the Client. This ensures the Client’s API base URL points to a running Server instance.
- Update the Client’s
BaseAddressinProgram.csto use your Server’s full App Service URL (instead of relying onbuilder.HostEnvironment.BaseAddress). - Create two Azure DevOps pipeline stages: one for deploying the Server to App Service, another for deploying the Client to Static Web Apps.
Either way, using Azure DevOps YAML pipelines is more maintainable than manual publishing—it automates builds, tests, and deployments consistently.
2. Fixing Client-Server Communication Errors in Azure Static Web Apps
Here are the most common fixes for this issue:
- Update API Base Address: In your Client’s
Program.cs, replace the relative base address with your Server’s full App Service URL. Example:client => client.BaseAddress = new Uri("https://your-server-appservice.azurewebsites.net/") - Configure CORS on the Server: Allow requests from your Static Web Apps domain by adding this to
ConfigureServicesinStartup.cs:
Then addservices.AddCors(options => { options.AddPolicy("AllowStaticWebApp", policy => policy.WithOrigins("https://your-staticwebapp.azurestaticapps.net") .AllowAnyHeader() .AllowAnyMethod()); });app.UseCors("AllowStaticWebApp");in theConfiguremethod (beforeUseRouting). - Verify Identity Server Configuration: Ensure the Client’s
appsettings.jsonpoints to the correct Identity Server authority (your Server’s URL):"IdentityServer": { "Authority": "https://your-server-appservice.azurewebsites.net" } - Check Static Web Apps Routing: If you’re using Static Web Apps’ built-in API (instead of a separate App Service), confirm
staticwebapp.config.jsonforwards API requests correctly. This isn’t needed if you’re using a separate Server App Service.
3. Troubleshooting After Publishing to Azure Windows App Service
First, undo the UseHttpsRedirection comment—Azure App Service provides a default SSL certificate for your app, so HTTPS works out of the box. Disabling this breaks Identity Server (which requires HTTPS by default), leading to authentication failures that break your app.
Follow these steps to fix the issue:
- Restore HTTPS Middleware: Re-enable
UseHttpsRedirectionandUseHstsin yourStartup.cs—Azure handles SSL automatically even without a custom certificate. - Validate Database Connection String: Your local
appsettings.jsonhas the connection string, but in Azure, you must set it in the App Service’s Configuration > Connection Strings section. Ensure the name matchesDefaultConnectionand the value is the correct Azure SQL DB connection string (copy this from the Azure SQL DB portal). - Apply Database Migrations: If you didn’t check "Apply migrations" during publishing, run them manually. Use the Azure CLI:
Or run this locally via Package Manager Console:az webapp deploy --resource-group <your-resource-group> --name <your-appservice-name> --src-path <path-to-server-publish-zip> --type zip --sql-connection-string <your-sql-connection-string>Update-Database -ConnectionString "<azure-sql-connection-string>" -ConnectionProviderName "Microsoft.Data.SqlClient" - Check App Service Logs: Go to the Azure Portal > Your App Service > Monitoring > Log Stream to view real-time error messages. Common issues include:
- Identity Server failing to start due to HTTPS being disabled
- Database connection failures (incorrect connection string)
- Missing migrations causing schema mismatches
- Confirm Static Files Are Published: Ensure the Blazor WASM client files are included in the Server’s publish output. When building the Server in Release mode, the Client’s
wwwrootshould be copied to the Server’swwwroot/_frameworkfolder.
内容的提问来源于stack exchange,提问作者MarchalPT

