namespace MyQuotesApp
{
public class Startup
{
// This method gets called by the runtime. Use this method to add services to the container.
// For more information on how to configure your application, visit http://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
loggerFactory.AddConsole();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseDefaultFiles();
app.UseStaticFiles();
//app.Run(async (context) =>
//{
// await context.Response.WriteAsync("Hello World!");
//});
app.UseMvc();
}
}
}
UseDefaultFiles pick these files by default.
default.htm
default.html
index.htm
index.html
If that not worked in your case. You can specify name of your default file with DefaultFilesOptions.
DefaultFilesOptions options = new DefaultFilesOptions();
options.DefaultFileNames.Clear();
options.DefaultFileNames.Add("index.html");
app.UseDefaultFiles(options);
You can also use app.UseFileServer();, it combines the functionality of
app.UseDefaultFiles();
app.UseStaticFiles();
Note: UseDefaultFiles must be called before UseStaticFiles to serve the default file. UseDefaultFiles is a URL re-writer that doesn't actually serve the file. You must enable the static file middleware (UseStaticFiles) to serve the file.
P.S. also update your packages to most latest.
Try this.
app.UseMvc(config =>
{
config.MapRoute(
name: "Default",
template: "{controller=*YourControllerName*}/{action=Index}/{id?}"
);
});
Related
After installing the React app template from .NET Core 3.1 using dotnet new react the application works perfectly in Development and Production. The problem appears when trying to use Swagger or Hangfire dashboard endpoints.
After the app is created I add the package reference for Hangfire and for practical purposes the memory storage:
<PackageReference Include="Hangfire" Version="1.7.*" />
<PackageReference Include="Hangfire.MemoryStorage" Version="1.7.0" />
In Startup.cs:
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
services.AddHangfire(config =>
config.SetDataCompatibilityLevel(CompatibilityLevel.Version_170)
.UseSimpleAssemblyNameTypeSerializer()
.UseDefaultTypeSerializer()
.UseMemoryStorage());
services.AddHangfireServer();
// In production, the React files will be served from this directory
services.AddSpaStaticFiles(configuration =>
{
configuration.RootPath = "ClientApp/build";
});
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
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.UseSpaStaticFiles();
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapHangfireDashboard();
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller}/{action=Index}/{id?}");
});
app.UseSpa(spa =>
{
spa.Options.SourcePath = "ClientApp";
if (env.IsDevelopment())
{
spa.UseReactDevelopmentServer(npmScript: "start");
}
});
}
After publishing the application and run it, the app works fine except the Hangfire dashboard, and trying to access the route: /Hangfire causes the server return the SPA index.html
But if I refresh the page doing a hard reload, the dashboard loads fine.
Same thing occurs with Swagger.
Can someone give me a hand ?
After following Guilherme suggestion, unregistering the service worker solved the issue. Instead of ignoring the routes, I opted to unregister it.
Thank you very much !
The template's default structure has everything in one place, like this:
/
bin/
obj/
ClientApp/
myproject.csproj
Startup.cs
etc.
My structure has many libraries and angular apps - i.e. a monorepo - so it must be more organized:
/
libs
client
client2
server
bin/
obj/
myproject.csproj
Startup.cs
lib1
lib2
I edited various references to reflect this structure, most importantly Startup.cs:
services.AddSpaStaticFiles(configuration => {
configuration.RootPath = "../../../../client/dist";
});
// and
app.UseSpa(spa => {
spa.Options.SourcePath = "../../../../client";
});
But when running I get: InvalidOperationException: Failed to start 'npm'.
When I run the server and client separately, they work... so the problem is with how the "spa services" is configured. I tried both ../../../../client (from bin directory) and ../client (from server project's base directory).
How do I reconfigure the project structure? (Is there a working sample repo somewhere?)
You can't run your app in dist folder when you are in development mode because dist folder only use for production mode
Default settings is like this
services.AddSpaStaticFiles(configuration =>
{
configuration.RootPath = "ClientApp/dist";
});
app.UseSpa(spa =>
{
spa.Options.SourcePath = "ClientApp";
if (env.IsDevelopment())
{
spa.UseAngularCliServer(npmScript: "start");
}
});
So in order to run your app you must create folder in same root of default Startup.cs or ClientApp file like in your case is libs then it will be libs/client
Then modify the setting
services.AddSpaStaticFiles(configuration =>
{
configuration.RootPath = "libs/client/dist";
});
app.UseSpa(spa =>
{
spa.Options.SourcePath = "libs/client";
if (env.IsDevelopment())
{
spa.UseAngularCliServer(npmScript: "start");
}
});
Please note that you can only run 1 angular app with this setting if you want to run another angular app you need to manage it selft manually
I got it working like this:
1 changed to monorepo structure as shown in my question above
2 edited Server.csproj (paths are relative to server app's directory):
<!--<SpaRoot>ClientApp\</SpaRoot>-->
<SpaRoot>../client/</SpaRoot>
3 edited Startup.cs (paths are relative to workspace's directory):
services.AddSpaStaticFiles(configuration => {
//configuration.RootPath = "ClientApp/dist";
configuration.RootPath = "./libs/client/dist";
});
and
app.UseSpa(spa => {
//spa.Options.SourcePath = "ClientApp";
spa.Options.SourcePath = "./libs/client";
// etc.
});
I am currently working with React and SignalR. I am using .Net Core 2.1 and the Microsoft.AspNetCore.App package to get the recent SignalR. I have installed #aspnet/signalr as well and I keep getting a 404 error because it is still attempting to go to the /negotiate endpoint which I know it doesn't use anymore. I have confirmed I am up to date on on all packages. Any pointers on where I should be going?
const hubConnection = new HubConnectionBuilder().withUrl('http://localhost:3000/ChatHub').build();
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.AddCors(o => o.AddPolicy("CorsPolicy", builder =>
//{
// builder
// .AllowAnyMethod()
// .AllowAnyHeader()
// .WithOrigins("http://localhost:3000");
//}));
services.AddSignalR();
//services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
// In production, the React files will be served from this directory
services.AddSpaStaticFiles(configuration =>
{
configuration.RootPath = "ClientApp/build";
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
//app.UseCors("CorsPolicy");
app.UseFileServer();
app.UseSignalR(routes =>
{
routes.MapHub<ChatHub>("/ChatHub");
});
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseSpaStaticFiles();
//app.UseMvc(routes =>
//{
// routes.MapRoute(
// name: "default",
// template: "{controller}/{action=Index}/{id?}");
//});
app.UseSpa(spa =>
{
spa.Options.SourcePath = "ClientApp";
if (env.IsDevelopment())
{
spa.UseReactDevelopmentServer(npmScript: "start");
}
});
}
I keep getting a 404 error because it is still attempting to go to the /negotiate endpoint which I know it doesn't use anymore
ASP.NET Core SignalR definitely still uses the /negotiate endpoint. In the previews, we used an OPTIONS request instead but that caused a lot of problems so we went back to the /negotiate endpoint.
It looks like you're using a "development server" (spa.UseReactDevelopmentServer in your Startup). That usually means that the development server is serving up your HTML/JS content from a different server than your ASP.NET Core app is running on (rather than just being static files served by the ASP.NET Core app). If that's the case, you need to reference the ASP.NET Core server using a full URL when you connect.
This is because your HTML/JS content is being served by the development server at http://localhost:X but your ASP.NET Core server is running at http://localhost:Y. So when you use /ChatHub as a URL, the browser interprets that as http://localhost:X/ChatHub, so you aren't hitting your ASP.NET Core app (with the SignalR server) but rather then dev server, which has no content at that URL and produces a 404.
On an ASP.NET Core view using AngularJs I have:
<div ng-include="'/views/profile.html'" ng-controller="ProfileController as c"></div>
When I change the HTML file and run the application its content does not change.
I checked it and the HTML file is cached ...
How can I avoid the caching of angular HTML templates in ASP.NET Core?
Actually this solution, I have got originally from the replies at the link given by #Deblaton in the comment here.
But, I modified for the purpose of ours'...
Just for development environment I disabled cache for only the HTML templates in the Configure() method of ASP.Net Core Request pipeline,
if (env.IsDevelopment())
{
app.UseStaticFiles(new StaticFileOptions()
{
OnPrepareResponse = (context) =>
{
if (context.File.Name.ToLower().EndsWith(".html"))
{
context.Context.Response.Headers["Cache-Control"] = "no-cache, no-store";
context.Context.Response.Headers["Pragma"] = "no-cache";
context.Context.Response.Headers["Expires"] = "-1";
}
}
});
}
else
{
app.UseStaticFiles();
}
And it just did the work!
Steps I took to setup project:
created new asp.net project
Install-Package Nancy.Viewengines.Razor
added Views/hello.cshtml (simple hello world html)
added MainModule.cs
hit ctrl-F5 (it returns the directory listing)
change url to localhost:41915/hello
Then I get 404 resource not found.
What am I missing?
// MainModule.cs
namespace MyProj
{
using Nancy.Routing;
using Nancy;
public class MainModule : NancyModule
{
public MainModule(IRouteCacheProvider routeCacheProvider)
{
Get["/hello"] = parameters => {
return View["hello.cshtml"];
};
}
}
}
You need the Nancy.Hosting.AspNet package too.