CSS folder not found on IIS .net core wwwroot - c#

Somehow I decided to build my web API and client separately after several hours failed to combine .net core 2.2 with vue+vuetify.
I build the client using Vue CLI, with this config:
module.exports = {
publicPath: process.env.NODE_ENV === 'production' ? '/joblist/' : '/',
}
Then place the content of dist folder to wwwroot folder on .net core project, I use below code to enable UseStaticFiles:
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseHsts();
}
app.UseDefaultFiles();
app.UseStaticFiles();
app.UseMvc();
}
Everything looks perfect when I debug with APP URL set to http://localhost:49602/joblist. But somehow when I publish to my Server, which is myserver/joblist, the server can't serve EVERYTHING placed inside wwwroot/css folder, so the site looks ugly.
At first, I thought the problem is the wwwroot path or something like that, but I can browse to wwwroot/js folder perfectly, so I try to rename wwwroot/css folder to wwwroot/notcss, the site works perfectly this time.
Can anybody help me with this problem?
UPDATE:
The wwwroot/css and wwwroot/js is perfectly exist on the server.
I can open any file inside wwwroot/js folder but can not open any
file inside wwwroot/css folder.
For now, I use a workaround by creating a hard link named wwwroot/notcss (can be any) then replace any /css/* reference in index.html file to /notcss/*
UPDATE 2
Here is the error I received on the browser when browse on one of any file in CSS folder
HTTP Error 404.0 - Not Found
The resource you are looking for has been removed, had its name changed, or is temporarily unavailable.
Detailed Error Information:
Module IIS Web Core
Notification MapRequestHandler
Handler StaticFile
Error Code 0x80070002
Requested URL http://localhost:80/joblist/css/app.14044b2f.css
Physical Path C:\inetpub\wwwroot\joblist\css\app.14044b2f.css
Logon Method Anonymous
Logon User Anonymous

There must be any some misscongured config, try to browse to C:\Windows\System32\inetsrv\config on your server, looks for a file named applicationHost.config open the file then search for css text. if you see some suspicious config just delete it, don't forget to backup it first.

Related

Could not find a part of the path virtual directory path c# [duplicate]

We have an application using ASP.NET Core 1.0 RC1 and hosted on IIS. It works fine. Now we have static content, that is available on a file share and should be accessible from the application.
Before ASP.NET 5, we added a virtual directory in IIS and could access the shared content easily. With our hosted ASP.NET 5 application, this unfortunately doesn't seem to work. We just get a 404 back when trying to access the static content.
Our application is using app.UseIISPlatformHandler() and app.UseStaticFiles(), but this doesn't work. We discovered that we could use app.UseFileServer() with custom FileServerOptions to get the desired behavior, but we are curious if it's also possible with the normal "old" way of adding a virtual directory in IIS.
I have found a blog which I think must have been written by the OP.
The upshot is not to use a virtual directory in IIS at all but rather map your path in Startup.cs to the physical server directory. I hope the OP does not mind that I have pasted the blog below, but it helped me when I first encountered this problem today.
Source: https://www.jauernig-it.de/asp-net-coreiis-serving-content-from-a-file-share/
There are situations, when you want to serve static content with your application, that is not part of it, e.g. because it exists on a common file share. Website content, that is managed by a business division, could be such a use case. In ASP.NET before Core, this was no problem in IIS: just create a virtual directory within your IIS website and point it to the file share.
Unfortunately, with ASP.NET Core, this approach isn’t working any longer. If you add a virtual directory to your ASP.NET Core application in IIS, it isn’t recognized and a 404 is returned. It’s because of DNX/Kestrel, which is running beneath IIS (using the HttpPlatformHandler module) and to which IIS only brokers the requests. Kestrel doesn’t know anything of virtual directories from IIS. And because ASP.NET Core applications are independent from IIS and could also be run without it (e.g. running Kestrel standalone), that should be considered as a good thing.
But now we need another solution for our problem… fortunately, ASP.NET Core gives us a programmatic interface to serve files from anywhere. Just add the following code to your Startup.cs Configure() method:
app.UseFileServer(new FileServerOptions
{
FileProvider = new PhysicalFileProvider(#"\\server\path"),
RequestPath = new PathString("/MyPath"),
EnableDirectoryBrowsing = false
});
What this essentially does, is adding a file server to a physical server path, that is then available on a certain request path, in this case with directory browsing disabled. You are also able to serve from a path relative to your application, using new PhysicalFileProvider(env.WebRootPath + "\path") (given env is of type IHostingEnvironment as parameter of Configure()). Voila, that’s it. There is no need to add a „virtual directory“ in IIS, this stuff is deprecated and a thing of the past. For me, this is a good thing, because we get more independent of the whole IIS…
I encountered this problem today, and finally managed to fix it. The trick (for me, probably not for everyone) is making sure the aspNetCore handler is disabled in the sub-application and enabled in the main (ASP.NET Core) application.
My ASP.NET Core app has a basic Web.config
<configuration>
<system.webServer>
<handlers>
<add name="aspNetCore" path="*" verb="*" type="" modules="AspNetCoreModule" scriptProcessor="" resourceType="Unspecified" requireAccess="Script" allowPathInfo="false" preCondition="" responseBufferLimit="4194304" />
</handlers>
<aspNetCore processPath="dotnet" arguments=".\bin\Debug\netcoreapp2.0\myapp.dll" stdoutLogEnabled="true" stdoutLogFile=".\logs\stdout" />
</system.webServer>
</configuration>
and the application added as a sub-application in IIS has
<configuration>
<!-- removed -->
<system.webServer>
<handlers>
<remove name="aspNetCore" />
</handlers>
</system.webServer>
</configuration>
I know its a question with 1,8 year, but if someone needs to resolve the same problem, try to use this:
public void Configure(IApplicationBuilder app)
{
app.UseStaticFiles(); // For the wwwroot folder
app.UseStaticFiles(new StaticFileOptions()
{
FileProvider = new PhysicalFileProvider(
Path.Combine(Directory.GetCurrentDirectory(), #"wwwroot", "images")),
RequestPath = new PathString("/MyImages")
});
}
Is perfectly possible to change parameters of PhysicalFileProvider to any local or shared folder, and with this serve a file.
Doing that in this way is not SECURITY recommended. But, for study propose, its acceptable.
The static file module provides no
authorization checks. Any files served by it, including those under
wwwroot are publicly available. To serve files based on
authorization: Store them outside of wwwroot and any directory
accessible to the static file middleware and Serve them through a
controller action, returning a FileResult where authorization is
applied.
In Microsoft's Asp.Net documentations we can find more complete information to help with this issue.
Check this link: https://learn.microsoft.com/en-us/aspnet/core/fundamentals/static-files
Not directly.
You see, the problem is, when you have a .NET-Core application, the application is run in Kestrell, not IIS (for .NET Core < 2.2).
Now, to host your .NET-Core application in IIS, the AspNetCoreModule starts your .NET-Core application with Kestrell on Port X of 127.0.0.1, and then reverse-proxies the traffic from your iis-domain+virtual directory to Port X on 127.0.0.1 (it might use something else than TCP).
Problem 1 is, Kestrell has pretty limited functionality, meaning no virtual directories.
Problem 2 is, unlike nginx, IIS does not really do the reverse-proxying properly, or should we say "completely".
IIS can forward domainxy:80 to 127.0.0.1:random alright.
But what it doesn't do properly is rewrite domainxy:80/foo to 127.0.0.1:random (images, header, json-ajax-results, urls, return-urls, cookies, etc. and vice-versa).
Instead it rewrites domain:80/foo to 127.0.0.1:random/foo, which is a problem if the server on 127.0.0.1:random (Kestrell) doesn't support virtual directories.
So if you want to run your application in your virtual-directory, you have two options (both involve modifying "your" application - if you can do that):
Put all your stuff into directory "foo" (including the MVC controller route), if your application is going to be deployed only once.
As suggested in https://github.com/aspnet/Hosting/issues/416#issuecomment-149046552 you can have the application-framework simulate that folder for you, kindof like in RoR:
public void Configure(IApplicationBuilder app,
IHostingEnvironment env,
ILoggerFactory loggerFactory)
{
string virtual_directory = "/Virt_DIR";
// virtual_directory = "/";
if (virtual_directory.EndsWith("/"))
virtual_directory = virtual_directory.Substring(0, virtual_directory.Length - 1);
if (string.IsNullOrWhiteSpace(virtual_directory))
Configure1(app, env, loggerFactory); // Don't map if you don't have to
// (wonder what the framework does or does not do for that case)
else
app.Map(virtual_directory, delegate(IApplicationBuilder mappedApp)
{
Configure1(mappedApp, env, loggerFactory);
}
);
}
// Configure is called after ConfigureServices is called.
public void Configure1(IApplicationBuilder app,
IHostingEnvironment env,
ILoggerFactory loggerFactory)
{
// [...] (here comes what used to be in your old Configure method)
}
You will have to configure the name of the virtual-directory somewhere.
Careful when you have/return URLs in JavaScript/ajax-requests, they won't be automagically mapped. You have to do this yourselfs, but that used to be this way with old ASP.NET, too.
Really, like RoR:
map Rails.application.config.relative_url_root || "/" do
    run RedmineApp::Application
end
As for a virtual directory within the application:
No, this is not that simple.
IIS is a full webserver, which will serve the content of that mapped directory like it was there (if it can read the contents).
If you forward the entire parent directory to Kestrell, then IIS can't serve the subdirectory, and you're application would have to do that. That means you'll have to setup a static file server for that specific directory, and tell it where the files are, as you have done.
What you might be able to do, is tell IIS to not proxy that specific virtual sub-directory (just as you can define a static-file location in nginx - except that IIS probably does not support that feature).
However, you could create a symlink (or mount/junction) within your application directory that goes to the networked folder, if Windows is capable of that (mklink). Then .NET Core should be able to serve it statically. But really, that sounds like a hack.
If you can't configure IIS, you really should use app.UseFileServer() and define the document's location in the database. That way you can just delete&re-insert the application later.
.Net Core has very limited support for IIS virtual directories.
As a workaround, you can use Microsoft.Web.Administration to get list of a Site ("Default Web Site") virtual directories.
Replace Path with PhysicalPath to locate the resources
Create a .NetStandard lib project (>= 1.6.0), and use this example
My solution was using path="/" instead of path="*" on web.config file

How to add SPA Services for AngularJS project with .NET Core?

I'm rebuilding a project of mine from .NET Framework to .NET Core and was curious to see if I'm able to "plug" in my Angular JS front-end project into the new .NET Core project using SpaServices. I've found some tutorials and this is what I have (my Angular folder is in the same project as my Startup.cs and API):
In ConfigureServices() in Startup.cs:
services.AddSpaStaticFiles(config => {
config.RootPath = "/MyAngularProject";
});
In Configure() in Startup.cs:
app.UseSpa(spa => {
spa.Options.SourcePath = "/MyAngularProject";
if (env.IsDevelopment())
{
spa.UseAngularCliServer(npmScript: "start");
}
});
The Angular folder is not named 'ClientApp'. When I run my backend and then the Angular project in VS Code, I get this error:
AggregateException: One or more errors occurred. (One or more errors occurred. (Failed to start 'npm'. To resolve this:.
[1] Ensure that 'npm' is installed and can be found in one of the PATH directories.
There is also an Inner Exception:
[2] See the InnerException for further details of the cause.
---> System.ComponentModel.Win32Exception (267): The directory name is invalid.
I've looked and made sure my PATH variable is set to the node.js folder and the error is still being thrown. I don't think I'm pointing at the wrong directory either for my Angular project. I do have the package.json file that holds the start script in a folder within MyAngularProject. I've also tried navigating into that folder but it produces the same errors. Can anyone help point me in the right direction? Is this even possible given the project is AngularJS? Thank you for any help!
UPDATE:
Here is the folder structure:
Solution 'MyProject'
MyProject.API
Controllers (folder)
MyAngularProject (folder)
app (folder)
[npm script is located in here]
Startup.cs
Program.cs
appsettings.json

Is it possible for user to escape asp.net core's application folder?

For example file css.css is accessible because it should be
access url:
localhost:1234/css.css
projects_folder
- application.dll
- wwwroot\css.css
but what about situation:
disk
secret_folder
- secret.txt
application_folder
- application.dll
- wwwroot\css.css
Can I safely assume that user is unable to this even with some tricks!:
localhost:1234/../secret_folder/secret.txt
in default ASP .NET Core's MVC template?
It depends on how the application is configured.
In the default ASP .NET Core's MVC template you should have the following in your Startup.Configure to allow access to static files in the wwwroot folder:
public void Configure(IApplicationBuilder app)
{
app.UseStaticFiles(); // For the wwwroot folder
}
The parameterless UseStaticFiles method overload marks the files in web root (wwwroot) as servable.
In order to access static files outside of the web root you would be required to add further configuration, as described in the following link:
https://learn.microsoft.com/en-us/aspnet/core/fundamentals/static-files?view=aspnetcore-2.1&tabs=aspnetcore2x

ASP.NET Core - Download .exe returns 404 error

I have a ASP.NET core MVC application and in the wwwroot folder, I've added another folder called "Shaun" and in that folder I've dropped an exe to try and download:
Now if I navigate to: http://localhost:PORT/Shaun/chromesetup.exe I get a 404 error. I've tried adding the Handler below but this doesn't work.
<add name="Client exe" path="*.exe" verb="*" modules="StaticFileModule" resourceType="File" />
Extra info: The reason I need to do this is because I have a client application that connects to this website, that client application is packaged using ClickOnce and gets dropped into the wwwroot of the website, this previously worked using MVC (pre Core) and still does, but doesn't with core.
How do I fix this?
Try the following and tell me if it works:
app.UseStaticFiles(new StaticFileOptions
{
ServeUnknownFileTypes = true, //allow unkown file types also to be served
DefaultContentType = "Whatver you want eg: plain/text" //content type to returned if fileType is not known.
}
You can look at the sourcecode of StaticFileMiddleware to see how it handles static files.
On default the FileExtensionContentTypeProvider is used to check based on filename extensions what ContentType needs to be return in the Http Response headers. exe is not in this list.
So another option would be to add Exe to this list:
var provider = new FileExtensionContentTypeProvider();
provider.Mappings.Add(".exe", "application/vnd.microsoft.portable-executable"); //file ext, ContentType
app.UseStaticFiles(new StaticFileOptions
{
ContentTypeProvider = provider
});
In order for static files (.exe file is a static file type) to be served, you must configure the Middleware to add static files to the pipeline. The static file middleware can be configured by adding a dependency on the Microsoft.AspNetCore.StaticFiles package to your project and then calling the UseStaticFiles extension method from Startup.Configure:
public void Configure(IApplicationBuilder app)
{
app.UseStaticFiles();
}

How to access a file from IIS web service hosted by ServiceHost

In my IIS application I open a file located in the wwwroot directory that way:
File.ReadAllText("ConfigFile.json");
IISExpress tries to open the file in C:\Program Files (x86)\IIS Express\ConfigFile.json
I thought the wwwroot directory was the working directory but apparently it's not the case.
Log4net log files are written relatively to the working directory, and configuration manager files also. So I don't understand why opening a file with System.IO.File I have C:\Program Files (x86)\IIS Express as the working directory.
What's the best solution for that problem ? I suppose I don't have to touch the Current defined working directory.
Ok, the solution that works in a IIS WCF Service, hosted by a ServiceHost class is:
AppDomain.CurrentDomain.BaseDirectory + "/ConfigFile.json"
It gives the full absolute path that is valid in my IIS Express environment and in the deployed IIS environment.
You will need to inject IHostingEnvironment into your class to have access to the ApplicationBasePath property value
Suppose IHostingEnvironment type is env then you can use
File.ReadAllText(env.WebRootPath + "/ConfigFile.json");
like you have a function named Read then you can use
public void Read(IHostingEnvironment env)
{
File.ReadAllText(env.WebRootPath + "/ConfigFile.json");
}

Categories

Resources