Using virtual directory with ASP.NET Core 3.1 - asp.net-core

In ASP.NET framework 4.8 and below version the web application use IIS for processing and show data. And when we need to work with other resource like folders and network resource we can easily create Virtual Directory in IIS and map to physical path and my application work theme like normal folder.
but in Net Core we use Kestrel and IIS work as a proxy and Virtual Directory not recognized by Kestrel. I use this code but not work in function. Write this section in Configure Function
app.UseFileServer(new FileServerOptions
{
FileProvider = new PhysicalFileProvider(#"E:\\MyFiles"),
RequestPath = new PathString("/PFiles"),
EnableDirectoryBrowsing = true
});
and this is my code :
var folder = Path.Combine(environment.WebRootPath, "temp");
var fileName = Path.Combine(environment.WebRootPath, "temp\\test.jpeg");
var basePath = Path.Combine(environment.WebRootPath, "PFiles");
var yearPath = Path.Combine(basePath, "2020");
var monthpath = Path.Combine(basePath, "2020", "06");
if (!Directory.Exists(yearPath))
{
Directory.CreateDirectory(yearPath);
}
if (!Directory.Exists(monthpath))
{
Directory.CreateDirectory(monthpath);
}
var dpath = Path.Combine(basePath, "2020", "06");
var destinationPath = Path.Combine(environment.WebRootPath, dpath);
System.IO.File.Move(fileName, destinationPath);
but I receive Access denied Error or create directory inside of wwwroot folder. So, what must I do?

you get this error because iis default account does not have enough permission to access the folder.
you could try to assign the iis_iusrs , iusr, or IIS AppPool<myappoolname> permission to the folder where you want to create directory.

Related

ASP.NET Core PhysicalFileProvider UNC error

Been trying to get this to work on my MAC for a while now, but still no luck.
In an ASP.NET Core app I am trying to get contents from my network share on a Windows Server. I read you can initiate Static Files through Startup.cs when you include:
app.UseFileServer(new FileServerOptions
{
FileProvider = new PhysicalFileProvider(#"\\192.168.178.101\2020$"),
RequestPath = new PathString("/2020"),
EnableDirectoryBrowsing = false
});
Please note I am running this on a MacOS laptop. I have tried SMB URL also, but no luck. I can connect with the share fine through Finder.
I always get the error "The path must be absolute". The share on that server is a folder named 2020. I have tried also without $, but no luck. I also tried to put smb:// in front, but the it saw the UNC as a relative folder path.
I really hope someone can help me with this.
The address format is not correct. It does not know the protocol. You can install nuget package SharpCifs and get file as:
var folder = new
SmbFile("smb://UserName:Password#ServerIP/ShareName/FolderName/");
var modeDate = new DateTime(2000, 1, 1, 0, 0, 0, DateTimeKind.Utc);
foreach (SmbFile item in folder.ListFiles())
{
var modeDate = epocDate.AddMilliseconds(item.LastModified()).ToLocalTime();
var name = item.GetName();
var type = item.IsDirectory() ? "dir" : "file";
var date = lastModDate.ToString("yyyy-MM-dd HH:mm:ss");
var msg = $"{name} ({type}) - LastMod: {date}";
}

Access IIS root directory from Asp.net core

I have shared appsettings in SharedSettings folder.
I am deploying all the asp.net core application in sub directory.
For development, I have created as site with the following directory
c://Website
Here I am keeping my sharedsettings.
But I am developing application from another folder. Here I have configured my application to run as sub application in the web sites.
Folder could be
c://Applications/App1
I want to include the sharedsettings.json in my application. So I have tried the following approach.
.ConfigureAppConfiguration((hostingContext, config) =>
{
var env = hostingContext.HostingEnvironment;
var sharedFolder = Path.Combine(env.ContentRootPath, "..", "Shared");
config
.AddJsonFile(Path.Combine(sharedFolder, "SharedSettings.json"), optional: true) // When running using dotnet run
.AddJsonFile("SharedSettings.json", optional: true) // When app is published
.AddJsonFile("appsettings.json", optional: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true);
config.AddEnvironmentVariables();
})
But whenever I have tried to get the hosted url path, It always current application hosted directory. (I understand the reason for the result).
But I don't know how to get the root directory path where it is pointing to the different location.
Reference:
https://andrewlock.net/sharing-appsettings-json-configuration-files-between-projects-in-asp-net-core/
According to your description, the only way to achieve your requirement is using Microsoft.Web.Administration library to select the site root path according to the asp.net core application root path.
Notice: If you want to use Microsoft.Web.Administration, you should make sure your application pool contains enough permission to access the applicationhost.config file.
Normally, we will need localsystem permission. About how to modify application pool permission, you could refer to this article.
Codes:
string path = env.ContentRootPath;
ServerManager mgr = new ServerManager();
//the root path is the parent website's root path
string rootpath = "";
foreach (var site in mgr.Sites)
{
foreach (var application in site.Applications)
{
foreach (var virtualDirectory in application.VirtualDirectories)
{
if (virtualDirectory.PhysicalPath == path)
{
rootpath = site.Applications[0].VirtualDirectories.Where(x=>x.Path=="/").Single().PhysicalPath;
}
}
}
}

.net core how to access shared folder on server outside project

I'm building a small app and want to access files (images) from a directory outside the project but on the same server the app will be running.
How can I access the directory I want?
I used this in Startup.cs inside Configure:
app.UseFileServer(new FileServerOptions()
{
FileProvider = new PhysicalFileProvider(env.ContentRootPath + "/Albums"),
RequestPath = new PathString("/Albums"),
EnableDirectoryBrowsing = true
});
And from Model that should be using it:
Initialize(_environment.WebRootPath + "/Albums");

.Netcore 2.0 and Virtual Directory

I have a .netcore 2.0 project running on IIS windows 2012.
There is an issue as I can't seem to get virtual directories working that exist outside of the root of the application. This works fine when the files are in the solution:
app.UseStaticFiles(new StaticFileOptions()
{
FileProvider = new PhysicalFileProvider(
Path.Combine(Directory.GetCurrentDirectory(), #"wwwroot", "images")),
RequestPath = new PathString("/MyImages")
});
The below does not however when outside of the root folder -
app.UseDirectoryBrowser(new DirectoryBrowserOptions()
{
FileProvider = new PhysicalFileProvider(Configuration["Keys:UploadFolder"]),
RequestPath = new PathString("/upload")
});
The reason for doing this is I have setup CI with octopus deploy. Each time I do a deployment the uploaded files are no longer there without using a virtual directory or creating some powershell script in octopus to copy them all over from last deployment.
Any recommendations or ways of resolving this in IIS with virtual directories in .netcore 2.0?

How do we set ContentRootPath and WebRootPath?

We're ending up with the following ContentRoot and WebRoot when we run our app from IIS.
ContentRoot: C:\MyApp\wwwroot
WebRoot: C:\MyApp\wwwroot\wwwroot
Here is how we are setting ContentRoot and WebRoot.
public class Startup
{
private readonly IHostingEnvironment _hostingEnv;
public Startup(IHostingEnvironment hostingEnv)
{
_hostingEnv = hostingEnv;
}
public void Configure(IApplicationBuilder app)
{
app.Run(context =>
{
// test output
context.Response.WriteAsync(_hostingEnv.ContentRootPath + "\r\n");
return context.Response.WriteAsync(_hostingEnv.WebRootPath + "\r\n");
});
}
public static void Main(string[] args)
{
var contentRoot = Directory.GetCurrentDirectory();
var webRoot = Path.Combine(contentRoot, "wwwroot");
var host = new WebHostBuilder()
.UseKestrel()
.UseIISPlatformHandlerUrl()
.UseContentRoot(contentRoot) // set content root
.UseWebRoot(webRoot) // set web root
.UseStartup<Startup>()
.Build();
host.Run();
}
}
From intellisense I see that...
ContentRootPath contains the application content files.
WebRootPath contains the web-servable content files.
How do we make the test output look instead like this:
ContentRoot: C:\MyApp\
WebRoot: C:\MyApp\wwwroot\
While RC2 documentation is still being prepared, here is what I learned while trying to deploy pre-RC2 app as Azure Web App:
There is no Visual Studio tooling yet, so the app must be published and deployed manually over FTP. For publishing, use: dotnet publish --configuration Release --output ./approot
If connected to Azure over FTP, you will probably see something similar to:
The "approot" folder can be replaced with the published one (the web.config is left in the approot).
The "approot" must be configured as a virtual application in Azure Portal (the default was site\wwwroot):
An the last thing to get static files served from the wwwroot folder, the Startup.cs file should be modified to include custom UseWebRoot call:
var currentDirectory = Directory.GetCurrentDirectory();
var host = new WebHostBuilder()
.UseKestrel()
.UseWebRoot(Path.Combine(currentDirectory, "..", "wwwroot"))
.UseDefaultHostingConfiguration(args)
.UseIISIntegration()
.UseStartup<Startup>()
.Build();
After these steps you should have ASPNET Core pre-RC2 web app running on Azure.
In RC2, if we put the web.config beside wwwroot and point IIS at the MyApp directory like this...
MyApp
web.config
wwwroot
...the code from the original question outputs this...
ContentRoot: C:\MyApp\
WebRoot: C:\MyApp\wwwroot\