Static Files Cannot be Found After Publishing to Linux on ARM - c#

I got an Web-API project, based on ASP.NET Core 2.1. This Web-API has to deliver static files from the default wwwroot folder. This works fine with the code below (from Startup.cs) on my Windows machine.
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseMvc()
.UseStaticFiles();
}
}
But when I publish the project for Linux on ARM (dotnet publish -r linux-arm) and pushing it to the test system, the static files cannot be retrieved by the browser. The Server returns always HTTP 404, no matter how the files are named and of course I respect upper and lower case on Unix systems, so it should not be realted to Asp.Net Core Web Application Static Files Gives 404 on Linux.
The wwwroot dir content is readable by the server process. I tested this by using File.ReadAllText(<full path to file in wwwroot>).
The server only runs on localhost and therefore the project does not use other servers, like ngingx.

I think I found out, what I did wrong. I started the Web-API by using the full path. Instead, I had to switch to the application directory first.
Working:
cd /home/myuser/testapp
./testapp
Not working:
/home/myuser/testapp/testapp
I did not change anything else and I can reproduce this, so switching to the app dir first, seems to be a must.

For anyone running your web application as a systemd service, you'll need to add the WorkingDirectory parameter
[Unit]
Description=Service Description
After=network.target
[Service]
WorkingDirectory=/path/to/parent_of_wwwroot
ExecStart=/path/to/dotnet /path/to/app
SyslogIdentifier=servicename
Restart=Always
User=serviceuser
Environment=DOTNET_ROOT=/path/to/parent_of_dotnet
[Install]
WantedBy=multi-user.target

Related

Asp.Net Core Web Api and Vue.js client with IIS

I'm trying to create an app with Asp.Net Core (.NET 6.0) as backend and Vue.js as frontend. I've created the .NET project inside Visual Studio 2022, added SPA Extensions and finally my Program.cs file look like this:
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
// Used by single page application requirements.
builder.Services.AddSpaStaticFiles(options =>
{
options.RootPath = "wwwroot";
});
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.UseStaticFiles();
if (!app.Environment.IsDevelopment())
{
app.UseSpaStaticFiles();
}
app.UseSpa(configuration =>
{
configuration.Options.SourcePath = "wwwroot";
if (app.Environment.IsDevelopment())
{
configuration.UseProxyToSpaDevelopmentServer("http://localhost:5002");
}
});
app.Run();
Deploying code with setttings:
Delete existing files
Configuration Release
Target net6.0 Framework
Target win-x64 Runtime
Produce me a folder containing wwwroot folder with frontend files and many files for my backend application. I put them in an application inside iis server with an application pool configured as:
.NET CLR Version 4.0
Integrated pipeline mode
But my application can only load index.html file but not any .js or .css.
My application has a binding like this:
https://app.domain.it/app-name and she try to open https://app.domain.it/filename.ext file each time, failing, since file is in a https://app.domain.it/app-name/wwwroot/file.ext and he's searching for https://app.domain.it/file.ext
Anyone could help me?
Edit 1: since I've selected Self-contained mode, I don't need the .NET 6 runtime installed on server host, right?
My recommendation is to create two different Application Pools and then deploy the .net core solution as your API (a) and the vue-app as your UI (b) separately.
(a) Standard Deployment with neither a project reference to UI-project nor a configuration of the pipeline regarding Static and default Files (app.UseStaticFiles(); app.UseDefaultFiles(); not necessary )
(b) right click on vue project in VS and "Open in Terminal" -> then npm run build -> then go to dist folder and copy content to physical path for respective application pool on IIS
Solution worked for me. Let me know if it is a solution for you as well and if you have any questions. Hope I could help you.

Why is HttpRepl unable to find an OpenAPI description? The command "ls" does not show available endpoints

I am working through the Microsoft Learn tutorials to "Create a web API with ASP.Net Core".
Under the heading, "Build and test the web API", at instruction (5) I am getting a response, "Unable to find an OpenAPI description".
For step (6) when executing the "ls" command I get the response, "No directory structure has been set, so there is nothing to list. Use the 'connect' command to set a directory structure based on an OpenAPI description". I have tried the "connect" command suggested here and have tried "dir" as an alternative to "ls".
I can successfully change directories in step (7) and execute the GET request for step (8) and receive the expected reply. However, it really bothers me the "ls" command is not working here and seems like an important function of the httprepl tool.
How can I get the "ls" command to work here or tell me why does it not work?
C:\Users\xxxx\source\repos\Learn\ContosoPizza>httprepl http://localhost:5000
(Disconnected)> connect http://localhost:5000
Using a base address of http://localhost:5000/
Unable to find an OpenAPI description
For detailed tool info, see https://aka.ms/http-repl-doc
http://localhost:5000/> ls
No directory structure has been set, so there is nothing to list. Use the "connect" command to set a directory structure based on an OpenAPI description.
http://localhost:5000/>
ADDED RESULTS OF SUGGESTIONS--
C:\Users\xxxx\source\repos\Learn\ContosoPizza>dotnet --version
3.1.412
C:\Users\xxxx\source\repos\Learn\ContosoPizza>dotnet add WebAPI.csproj package Swashbuckle.AspNetCore -v 5.6.3
Could not find project or directory `WebAPI.csproj`.
httprepl GitHub repo and MS Docs page
The solution for me was to simply trust localhost's SSL certification, which you can do with this command:
dotnet dev-certs https --trust
While doing the same Tutorial, a friend of mine noticed, that trusting the dev certificate, was already covered by the Tutorial, which I had overlooked doing the Tutorial myself. This is the official help site:
Trust the ASP.NET Core HTTPS development certificate on Windows and macOS.
Maybe this will still help someone with the same problem.
In step 5 HttpRepl emits the warning Unable to find an OpenAPI description, which means that it can't find the swagger endpoint, and therefore the ls command wont work.
I assume you are using VS Code and ASP.NET Core 5.0. Here is my output from running dotnet --version:
5.0.401
If we are using Visual Studio, then remember to enable swagger when you create the project - I am using Visual Studio 2019 to create the screenshot:
Specifying your OpenAPI description
To find out which endpoint to use, open the file Startup.cs and locate the code fragment that contains the text UseSwaggerUI. You should find this block of code:
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseSwagger();
app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "WebAPI v1"));
}
Use the endpoint you find and run the tool like this:
httprepl http://localhost:5000 --openapi /swagger/v1/swagger.json
If you do not find any references to swagger, then see None of the above worked, swagger isn't installed below, for how to install and configure swagger for your project.
Ignoring your environment
If specifying the Open API endpoint to use doesn't work, then you are not running your Web API in a development environment. So either use a development environment, or uncomment the if-statement while testing (to setup your environment for development, see Changing your environment below):
//if (env.IsDevelopment())
//{
app.UseDeveloperExceptionPage();
app.UseSwagger();
app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "WebAPI v1"));
//}
Remember to restore the code you uncommented, if any, before you deploy to production.
Changing your environment
The profile your Web API is using, is specified in the file Properties\launchSettings.json. Open the file and search for ASPNETCORE_ENVIRONMENT. Then change the instances you find to:
"ASPNETCORE_ENVIRONMENT": "Development"
If this doesn't work, or the instances were already set to "Development", it means that you are not using any of the profiles specified in your launch settings. If no profile is used, ASPNETCORE_ENVIRONMENT defaults to "Production". When using the dotnet run command, the --launch-profile parameter lets you specify which profile to use:
dotnet run --launch-profile "name_of_profile"
As a last resort you can set the environment variable ASPNETCORE_ENVIRONMENT in the shell you are using, before you run the command dotnet run:
Bash
export ASPNETCORE_ENVIRONMENT=Development
CMD
set ASPNETCORE_ENVIRONMENT=Development
PowerShell
$env:ASPNETCORE_ENVIRONMENT='Development'
Then run the application without a profile :
dotnet run --no-launch-profile
The default ports, when running without a profile, should be 5000 or 5001. But read the output from the command, to see which ports it assigns to your Web API.
Please note, if you use VS Code to run your project, that VS Code may also have created launch settings in the .vscode\launch.json. It depends on how you have configured VS Code and what you allow it to do. I found some older articles, that claim that some extensions for VS Code, may interfere with the launch settings, but they didn't specify which ones.
None of the above worked, swagger isn't installed
I none of the above worked, it means you don't have swagger installed. Install swagger for your project and when done, try again.
Package Installation
Open your project in VS Code and run the following command from the Integrated Terminal and replace WebAPI.csproj with the name of your own project file:
dotnet add WebAPI.csproj package Swashbuckle.AspNetCore -v 5.6.3
You can of course run the command from outside VS Code, with your project folder as the current working directory.
Add and configure Swagger middleware
Add the Swagger generator to the services collection in the Startup.ConfigureServices method, as the last statement in the method:
public void ConfigureServices(IServiceCollection services)
{
[... other code here ...]
// Register the Swagger generator, defining 1 or more Swagger documents
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "WebAPI", Version = "v1" });
});
}
In the Startup.Configure method, enable the middleware for serving the generated JSON document and the Swagger UI, at the top of the method:
public void Configure(IApplicationBuilder app)
{
// Enable middleware to serve generated Swagger as a JSON endpoint.
app.UseSwagger();
// Enable middleware to serve swagger-ui (HTML, JS, CSS, etc.),
// specifying the Swagger JSON endpoint.
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
});
[... other code here for setting up routing and the like ...]
}
To learn more about setting up swagger, profiles and the environment
Get started with Swashbuckle and ASP.NET Core
Managing Production and Development Settings in ASP.NET Core
Use multiple environments in ASP.NET Core
ASP.NET Core web API documentation with Swagger / OpenAPI
I had faced same issue. I have solved it by following:
In Developer PowerShell(VS 2022), Run 'dotnet run' command.
Keep this powershell as it is.
Now open new PowerShell and run "httprepl https://localhost:{PORT}"
You should be able to run api now.
You must be connected to the web server through dotnet run.

Static file not served through IIS but serving through localhost - ASP.NET Core 3.1 MVC & C#

I am new to programming, and I was able to solve most of the issues all by myself. But this issue goes over my head.
I am using Visual Studio to run my app locally. When I click on "IIS Express" within VS to run the app, the app is opening in a browser with url http://localhost:1234/ and serving static files.
However when I use IIS to host my app, like when I type myapp.com in my browser, I am seeing website in plain text. And no static files (css, js) are being served.
Not sure what is causing the issue. I googled for long time and read lot of posts, but most of them are asking to check if IIS has static role service turned or suggesting to use app.UseStaticFiles() within startup.cs file. Which in my case is done.
program.cs:
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
})
Startup.cs:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseDefaultFiles();
app.UseStaticFiles();
}
Any help is much appreciated.
I didnt know that when we publish it to "files and folder" from Visual studio, any changes that we make in Visual studio will not go through to published folder. Because of this reason "app.UseStaticFiles();" command (that I wrote after publishing) is not passed on to published folder. I had to delete the published folder and republish to make everything work fine.

Cannot find module 'aspnet-webpack' when using 'dotnet publish' in .Net Core 2.0 & Angular

I have been trying to follow answers to this problem but to no avail.. I am trying to publish my .Net Core 2.0 & Angular project using the command line command 'dotnet publish' I successfully publish, however when trying to run my project's .dll in the published folder, my project spits in out this error when run in a development environment:
Unhandled Exception: System.AggregateException: One or more errors occurred. (Webpack dev middleware failed because of an error while loading 'aspnet-webpack'. Error was: Error: Cannot find module 'aspnet-webpack'
When run in Production and allowing for the DeveloperExceptionPage (as shown in my statup.cs below) the .netcore app runs, but crashes within the actual web app, which I assume is due to the larger error, aspnet-webpack not being found:
NodeInvocationException: Uncaught (in promise): Error: No component factory found for HomeComponent. Did you add it to #NgModule.entryComponents?
Startup.cs
public class Startup
{
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.AddMvc();
}
// 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();
app.UseWebpackDevMiddleware(new WebpackDevMiddlewareOptions
{
HotModuleReplacement = true
});
}
else
{
//app.UseExceptionHandler("/Home/Error");
app.UseDeveloperExceptionPage();
}
app.UseStaticFiles();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
routes.MapSpaFallbackRoute(
name: "spa-fallback",
defaults: new { controller = "Home", action = "Index" });
});
}
}
I am not using #Angular/Cli, but I am using the default Angular Project that VS2017 (August update, I believe?) generates, which seems to only use Webpack. The problem seems to be that the Production config of the project expects a reference that I am not providing, but I can not figure out why that is.
No other answers to this question have helped me thus far, so I apologize if this is a repeat question.
After you publish your .Net Core 2.0 & Angular project, and before you run it, you need to ensure that the environment variable ASPNETCORE_ENVIRONMENT isn't set to Development. The published project doesn't include support for the WebpackDevMiddleware or HotModuleReplacement. But it will attempt to use them if the environment is set to Development.
HotModuleReplacement automatically updates Webpack-built resources (such as JavaScript, CSS, or images) in your web browser whenever source files are changed. This is obviously something that you don't want in production.
If ASPNETCORE_ENVIRONMENT is set to "Development", you can change the setting with:
setx ASPNETCORE_ENVIRONMENT "Production"
You will need to close the current command window and open another to see the change.
You can also comment out the following code in startup.cs to accomplish the same result:
#if DEBUG
app.UseWebpackDevMiddleware(new WebpackDevMiddlewareOptions
{
HotModuleReplacement = true
});
#endif
Make sure you have fully installed all of these dependencies:
npm install webpack-hot-middleware --save-dev
npm install webpack-dev-middleware --save-dev
npm install aspnet-webpack --save-dev
In my case the cause was that the SPA (Vue in my case) is in the ClientApp folder and app.UseWebpackDevMiddleware expects it to be in the project root.
Setting the ProjectPath option solved this for me.
app.UseWebpackDevMiddleware(new WebpackDevMiddlewareOptions
{
HotModuleReplacement = true,
ConfigFile = Path.Combine(env.ContentRootPath, #"ClientApp\node_modules\#vue\cli-service\webpack.config.js"),
ProjectPath = Path.Combine(env.ContentRootPath, #"ClientApp")
});
I had same issue with "aspnet-webpack", this was introduced halfway in the project development so I was bit surprised to see sudden death of the solution. It was all working fine couple of months on IIS but suddenly failed to boot.
IIS log files were not helpful, so I tried to resolve this couple of ways, one of them worked. Hurry!
Solution
I ran following on package-manager window :
dotnet run --project <Full path of *.csproj> --configuration Debug
It give me some pointers and I started searching for "Error: Cannot find module 'aspnet-webpack'" issue. I tried to go through all the changes for last couple of check-ins, and found out that we updated the "Microsoft.AspNetCore.All" from 2.0.0 to 2.0.3 version, so downgrading it to original version fixed it.
I guess they both uses different versions of node packages. So don't update for sake unless for a very good reason. Reading around this some bits are very tightly coupled to specific versions and Angular very easily breaks, if something changed. In process though I have managed to upgrade the node version to latest 5.0.0
Love to find more details, but for time being no details on why it needs a specific version.
I got the same error as you in a project without Angular:
Unhandled Exception: System.AggregateException: One or more errors occurred. (Webpack dev middleware failed because of an error while loading 'aspnet-webpack'. Error was: Error: Cannot find module 'aspnet-webpack'
Turned out to be a simple problem with node that I tend to forget.
npm install
Remember that npm commands need to be run in the top directory which contains your package.json file. I hope that this helps someone who has as much problems as me remembering to actually run npm commands. Thanks to the forum which reminded me:
https://www.ebenmonney.com/forum/?view=thread&id=20&part=1#postid-57
Check that node.js is installed in production and is in the path.
Node.js is used by webpack
Also check that you have a recent version of Node.js (4+)
Reference : AspNetCore + Angular 2: WebpackDevMiddleware Error with new project
Version of Node.js can be checked with :
where.exe node.exe (Windows 7+)
which node.exe (linux bash)
And of course path environment variable should be checked and updated if pointing to obsolete Node.js
All the best
AT configure function of startup.cs You can use if statement for development environment
if (env.IsDevelopment())
{
// Print exception and all details for the developer
app.UseDeveloperExceptionPage();
// Use WebPack to update css , js , html automatically
app.UseWebpackDevMiddleware(new WebpackDevMiddlewareOptions
{
HotModuleReplacement = true
});
}
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();
}
You can this comman in command print to change current environment :
setx ASPNETCORE_ENVIRONMENT "Development"
The main reason for this error is that you are using a dependency somewhere in your code and it isn't installed in your solution. If you are using visual studio, try using clean build, it will show up the errors in your project which'll help you in finding it.

Running ASP.NET 5 Cross-Platform

I'm interested in ASP.NET 5 on my Windows and Mac OS machines. To get started, I installed Visual Studio 2015 RC on my Windows machine. I created a new, empty web site for ASP.NET 5 (aka vNext). I updated the template with a Views directory and included the MVC and Static Files nuget packages. I can successfully run this "Hello World" app. I also was successful in checking it into GitHub and automatically deploying it to Azure as a Website.
Then, I cloned the repository on my Mac OS machine. I successfully ran dnu restore to get the packages. I then ran dnx . run. When I do this, I get an error though. The error is:
'Website' does not contain a static 'Main' method suitable for an entry point
What am I doing wrong? I have a Startup.cs file. I know it works based on the fact that it runs on Windows and in Azure. Yet, I can't figure out what I'm missing. My Startup.cs file looks like this:
Startup.cs
using Microsoft.AspNet.Builder;
using Microsoft.AspNet.Hosting;
using Microsoft.Framework.ConfigurationModel;
using Microsoft.Framework.DependencyInjection;
namespace Test.Site.Web
{
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
}
public void Configure(IApplicationBuilder app)
{
app.UseErrorPage();
app.UseStaticFiles();
app.UseMvc(routes =>
{
routes.MapRoute("default",
"{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index" });
});
app.UseMvc();
app.UseWelcomePage();
}
}
}
What did I do wrong?
In your project.json file, there should be a set of commands to run the project. By default, one of those is web and one is kestrel. Kestrel is the server for OS X and Linux, it's based on libuv, the same library that powers Node.
"commands": {
"gen": "Microsoft.Framework.CodeGeneration",
"kestrel": "Microsoft.AspNet.Hosting --server Kestrel --server.urls http://localhost:5004",
"web": "Microsoft.AspNet.Hosting --server Microsoft.AspNet.Server.WebListener --server.urls http://localhost:5002"
},
(I don't have VS 2015 in front of me at the moment, so I'm not 100% sure of the default commands in an "empty" project, so you may need to add the kestrel command).
So run this command to start your server on OS X or Linux:
dnx . kestrel
If you were starting it from the command prompt on Windows, you'd use:
dnx . web
Note you can customize the commands however you like. For example, one command might generate the database. Another might analyze the server for system requirements. One might even uninstall the application!

Categories