To use UseSpaStaticFiles, you must first register an ISpaStaticFileProvider in Azure Service Fabric
I'm using the latest version of SPA templates: Microsoft.DotNet.Web.Spa.ProjectTemplates::2.0.0
Creating Angular app by:
and getting the following error when deploy it in Azure SF stateless service:
Unhealthy event: SourceId='System.RA', Property='ReplicaOpenStatus', HealthState='Warning', ConsiderWarningAsError=false.
Replica had multiple failures during open on _Node1_0. API call: IStatelessServiceInstance.Open(); Error = System.InvalidOperationException (-2146233079)
To use UseSpaStaticFiles, you must first register an ISpaStaticFileProvider in the service provider, typically by calling services.AddSpaStaticFiles.
at Microsoft.Extensions.DependencyInjection.SpaStaticFilesExtensions.ShouldServeStaticFiles(IApplicationBuilder app, Boolean allowFallbackOnServingWebRootFiles, IFileProvider& fileProviderOrDefault)
at Microsoft.Extensions.DependencyInjection.SpaStaticFilesExtensions.UseSpaStaticFilesInternal(IApplicationBuilder app, StaticFileOptions staticFileOptions, Boolean allowFallbackOnServingWebRootFiles)
at AppApiGateway.Startup.Configure(IApplicationBuilder app, IHostingEnvironment env) in C:\Users\Yatajga\Source\Repos\DistrTest\src\ServiceFabric\AppApiGateway\Startup.cs:line 68
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at Microsoft.AspNetCore.Hosting.ConventionBasedStartup.Configure(IApplicationBuilder app)
at Microsoft.AspNetCore.Hosting.Internal.WebHost.BuildApplication()
at Microsoft.AspNetCore.Hosting.WebHostBuilder.Build()
at AppApiGateway.AppApiGateway.<>c__DisplayClass1_0.b__1(String url, AspNetCoreCommunicationListener listener) in C:\Users\Yatajga\Source\Repos\DistrTest\src\ServiceFabric\AppApiGateway\AppApiGateway.cs:line 44
at Microsoft.ServiceFabric.Services.Communication.AspNetCore.AspNetCoreCommunicationListener.OpenAsync(CancellationToken cancellationToken)
at Microsoft.ServiceFabric.Services.Runtime.StatelessServiceInstanceAdapter.d__19.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.ServiceFabric.Services.Runtime.StatelessServiceInstanceAdapter.d__13.MoveNext()
For more information see: http://aka.ms/sfhealth
internal sealed class AppApiGateway : StatelessService
public AppApiGateway(StatelessServiceContext context)
: base(context)
/// <summary>
/// Optional override to create listeners (like tcp, http) for this service instance.
/// </summary>
/// <returns>The collection of listeners.</returns>
protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
return new ServiceInstanceListener[]
new ServiceInstanceListener(serviceContext =>
new KestrelCommunicationListener(serviceContext, "ServiceEndpoint", (url, listener) =>
ServiceEventSource.Current.ServiceMessage(serviceContext, $"Starting Kestrel on {url}");
// Read environment from config files
var environment = FabricRuntime.GetActivationContext()?
.GetConfigurationPackageObject("Config")?
.Settings.Sections["Environment"]?
.Parameters["ASPNETCORE_ENVIRONMENT"]?.Value;
return new WebHostBuilder()
.UseKestrel()
.ConfigureServices(
services => services
.AddSingleton<StatelessServiceContext>(serviceContext))
.UseContentRoot(Directory.GetCurrentDirectory())
.UseStartup<Startup>()
.UseEnvironment(environment)
.UseServiceFabricIntegration(listener, ServiceFabricIntegrationOptions.None)
.UseUrls(url)
.Build();
}))
// This method gets called by the runtime. Use this method to add services to the container.
public IServiceProvider ConfigureServices(IServiceCollection services)
services.AddSignalR();
services.AddMvc();
services.AddSingleton<IClusterClient>(sp =>
OrleansConfiguration.StartClientWithRetries(out var client);
return client;
});
var container = new ContainerBuilder();
container.Populate(services);
// In production, the Angular files will be served from this directory
services.AddSpaStaticFiles(configuration =>
configuration.RootPath = "ClientApp/dist";
});
return new AutofacServiceProvider(container.Build());
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
app.UseSignalR(routes =>
routes.MapHub<ProductMessageHub>("ProductMessageHub");
});
if (env.IsDevelopment())
app.UseDeveloperExceptionPage();
app.UseExceptionHandler("/Home/Error");
app.UseStaticFiles();
app.UseSpaStaticFiles();
app.UseMvc(routes =>
routes.MapRoute(
name: "default",
template: "{controller}/{action=Index}/{id?}");
});
app.UseSpa(spa =>
// To learn more about options for serving an Angular SPA from ASP.NET Core,
// see https://go.microsoft.com/fwlink/?linkid=864501
spa.Options.SourcePath = "ClientApp";
if (env.IsDevelopment())
spa.UseAngularCliServer(npmScript: "start");
});
To use UseSpaStaticFiles, you must first register an ISpaStaticFileProvider in Azure Service Fabric
dotnet/Scaffolding#831