dynamicweb / DynamicWeb

Make feature requests for Dynamicweb in Issues section of this repository
https://doc.dynamicweb.dev/documentation/fundamentals/support/feature-requests.html
GNU General Public License v3.0
1 stars 0 forks source link

Allow Relative File Path in AppSettings.Json for the FilesPath setting #158

Open joeyCV93 opened 1 month ago

joeyCV93 commented 1 month ago

I have already created https://github.com/dynamicweb/DynamicWeb/issues/124 which i believe was closed without a true resolution.

Original Issue

Is your feature request related to a problem? Please describe. We have had a problem where we are using a separate Swift Repo for our project, forked from https://github.com/dynamicweb/Swift. This is a problem as we have a configuration where each developer working on the project, will clone down both the DynamicWeb repo and the Swift repo to the same folder on their local machine, and should be able to just run the DynamicWeb solution and it pick up the correct Files directory of the Swift repo. This does not work as expected as the code in the DynamicWeb startup will not allow relative file paths, and instead when it detects that the path is relative, will append the root of the DynamicWeb repository to it. This means that it cannot detect the correct path of the Swift repo as it is outside the root of the DynamicWeb repo.

This is the appSettings,Json value i am referring to:

"FilesPath": "DynamicWebSwift\\Swift\\Files"

Our Folder structure of the checked-out repos is:

<Their Base Folder for Git repos>/DynamicWebSwift/Swift/Files <Their Base Folder for Git repos>/DynamicWeb Describe the solution you'd like It would be good to update the following method: builder.Services.AddDynamicweb(builder.Environment, builder.Configuration); to also take in a boolean of useRelativeFilesPath that will allow the swift repo to be used without working around or copying it into the DynamicWeb rep folder.

If an absolute path is required inside this method, it should work out what the absolute path of the given relative path from the "FilesPath" appSettings value from the Hard drive root rather than assuming it will be inside the DynamicWeb repo folder.

Describe alternatives you've considered We have two options to work around this and neither are ideal:

Each developer must change appSettings.json FilesPath variable to be their full path they have checked out the code to: E.g C:\Users\<USERNAME>\<Their Base Folder for Git repos>\DynamicWebSwift\Swift\Files

This is extra work for each developer and not something that certain front-end developers may want to do. It also is prone to someone accidentally checking this in, as we cannot exclude appSettings.json from the repo using .gitignore.

Extra Code in Program.cs that will overwrite the Variable once it has been loaded into memory, and before builder.Services.AddDynamicWeb() has executed. This needs to programatically convert the relative path to a absolute path. We have implemented this approach, but it is not a clean or ideal solution, and is something that we shouldn't have to do at all really.

var builder = WebApplication.CreateBuilder(args);
OverrideSwiftFilesDirectory(builder);
builder.Services.AddDynamicweb(builder.Environment, builder.Configuration);

//...

void OverrideSwiftFilesDirectory(WebApplicationBuilder webApplicationBuilder)
{
    var directoryInfo = new DirectoryInfo(Environment.CurrentDirectory);
    var appSettingsPath = webApplicationBuilder.Configuration.GetValue<string>("FilesPath");
    var projectsRoot = directoryInfo.Parent?.Parent?.ToString();
    if (!string.IsNullOrEmpty(appSettingsPath) && !string.IsNullOrEmpty(projectsRoot))
    {
        webApplicationBuilder.Configuration["FilesPath"] = Path.Combine(projectsRoot, appSettingsPath);
    }
}

Additional context The Source of the issue is this line:

filesPath = flag ? (Path.IsPathRooted(filesPath) ? filesPath : Path.Combine(environment.ContentRootPath, filesPath)) : Path.Combine(str, "Files");

Which is in DynamicwebApplicationExtensions.AddDynamicweb() Line:72 Microsoft.AspNetCore.Builder.DynamicwebApplicationExtensions.AddFileProviders() Line:149

Additional context not in the previous issue raised which was closed

This was the response:

Hi joeyCV93,

DynamicWeb 10 does support relative paths, see here. In DW10, the root path is the application/host folder. This is the folder you move relatively to, unless your path is absolute. You can move up the folder structure by using double dots.

If your application is located at <git folder>\DynamicWeb and Swift is located at <git folder>\DynamicWebSwift\Swift\Files, you can simply put ..\\ in front of your FilesPath. Your appsettings.json would look like this:

{
    "FilesPath": "..\\DynamicWebSwift\\Swift\\Files"
}

If you need to move further up, you can chain as many double dots as the folder structure will allow. At start-up, DynamicWeb will resolve the path to an absolute path and use that for the lifetime of the application. You can see the calculated absolute path to the files folder when DynamicWeb starts up. See the output log from Kestrel in the terminal. If you're using IIS, you need to enable logging output in you Web.config to see it.

I have stepped through the startup process to prove that the relative path does not work as suggested by dw-jea.

My "relative" files path

image

image

When the app starts and AddFileProviders() executes inside AddDynamicweb() and it detects the path is relative. it gets the ContentRootPath which locks the root down to the folder of the DW Solution, so a Swift solution that is a sibling folder rather than a child is not accessible.

image

This then incorrectly concatenates the paths together. Forcing the incorrect Root and making it invalid as it doesnt respect the relative .. as suggested by dw-jea

image

This then throws an exception and the app quits

image

Therefore, i don't think the original issue should have been closed without a resolution. This is an issue with the way DynamicWeb handles relative file paths.

dw-jea commented 1 month ago

My answer is the same as in the previous issue. DynamicWeb 10 supports relative paths out of the box. Yes, it uses ContentRootPath to determine to root of the application. According to Microsoft, this is the root of the application, so I see no issue with using that. Also, what would the alternative be? Where would you start from if not from the root of the application?

Perhaps the issue here is that content root can be calculated differently depending on how the application is started? Here's what I mean.

You can override the content root path by either creating your own host builder in Program.cs or use an environment variable. I don't know what the consequences of that would be, but if you want, you can try it out.

I can't tell from your screenshots, how your project is structured, but I assume you have your project file in the Src folder. When you start the application, whether it's from Rider or the command line, the content root will be the Src folder.

Assuming a folder structure like this C:\U\JC\D\GH\Website2\Src and C:\U\JC\D\GH\Swift. You need two double dots in front of the Files path: ..\..\Swift. This is because you need to go up two levels and not just one (from Src to Website2 and again from Website2 to GitHub). The resolved path in your example is C:\U\JC\D\GH\Website2\Swift.

This is also mentioned in my original answer: If you need to move further up, you can chain as many double dots as the folder structure will allow. You are not locked by the content root, this is merely the starting point. The only thing you need to ensure is that the account running the app process has read/write access to the given Files folder, but that's always necessary no matter where it is.

I'm not sure how else to explain it. This is working as intended.