4

I'm using static files middleware to access customer specific resources located outside wwwroot. These resources include CSS and image files, and are accessible at ~/resources. For example, customer-specific css is located here :

 <link rel="stylesheet" href="~/resources/css/customer.css" />

Now I would like to serve a static html file located in ~/resources/html/static.html. I created a model which contains only a HtmlString property, and I wish to inject the content of static.html inside a standard cshtml using this model. Here is my controller action :

public IActionResult MentionsLegales()
{
    var filePath = IO.Path.Combine(
        _env.ContentRootPath, "PersonnalisationClient", _config["PersonnalisationClient:NomClient"], "html", "mentionslegales.html");

    var mentionsLegalesModel = new MentionsLegalesModel();

    if (IO.File.Exists(filePath))
        mentionsLegalesModel.Content = new Microsoft.AspNetCore.Html.HtmlString(IO.File.ReadAllText(filePath));
    else
    {
        _logger.LogWarning($"Le fichier {filePath} est introuvable");
        mentionsLegalesModel.Content = new Microsoft.AspNetCore.Html.HtmlString(string.Empty);
    }
    return View(mentionsLegalesModel);
}

As you can see, here I access the file through its physical path. It's working but I'm not satisfied with this solution. I wanted to read the file through its server path, which is ~/resources/html/mentionslegales.html, but I don't know how to do that. Apparently in non-Core MVC one could use Server.MapPath for such purpose, but I couldn't find an equivalent in MVC core. Do you have any ideas ?

6
  • Path.Combine(_env.ContentRootPath, "resources/html/mentionslegales.html") allows you to use the server path (as a relative path though) Commented Oct 14, 2019 at 12:18
  • Thanks for your comment, but that's already what I tried to do. _env.ContentRootPath gives me the absolute physical path : C:\\Users\\xxx\\.... What I want is to read the file from its relative server URI : ~/resources/html/mentionslegales.html. Commented Oct 14, 2019 at 12:48
  • "that's already what I tried to do" - well, IO.Path.Combine( _env.ContentRootPath, "PersonnalisationClient", _config["PersonnalisationClient:NomClient"], "html", "mentionslegales.html"); looks to me like you're building the path manually, rather that letting Path.Combine combine it for you. There is no equivalent of Server.MapPath in ASP net core, so using IHostingEnvironment is your only option. Commented Oct 14, 2019 at 14:38
  • I don't think I misuse Path.Combine as you suggest, it's buiding a correct physical path. I was just looking for another way to do that, because I'm afraid the physical path would change depending on where the app is published. I wish I was able to easily load my static html from the controller, using a relative URI. Commented Oct 14, 2019 at 14:59
  • Sorry, I wasn't suggesting it was misusing it, just that if you wanted to use the 'server path' you could combine that with the content root. Commented Oct 14, 2019 at 15:05

1 Answer 1

4

If you want to call the static resources in the folder outside the web root directory in the page, you could configure the Static File Middleware in Configure method as follows:

app.UseStaticFiles(); // For the wwwroot folder

app.UseStaticFiles(new StaticFileOptions
{
    FileProvider = new PhysicalFileProvider(
        Path.Combine(Directory.GetCurrentDirectory(), "resources")),
    RequestPath = "/resources"
});

Then reference the file like below:

 <link rel="stylesheet" href="~/resources/css/customer.css" />

return View() is reserved for returning the result of a view execution, i.e. a Razor CSHTML page. You can't use an HTML page for that.Try to redirect directly:

return Redirect("~/resources/html/mentionslegales.html");

Refer to the links below which may be help you better understand how to return static html pages from the controller.

How to make a get request for an HTML file using ASP.NET Core MVC

https://github.com/aspnet/Mvc/issues/3751

Update:

For injecting the static html in the View , you could refer to :

Controller

 public IActionResult GetStaticFile()
 {
        var mentionsLegalesModel = new MentionsLegalesModel();
        var htmlString = System.IO.File.ReadAllLines("./resources/html/mentionslegales.html");
        mentionsLegalesModel.Content = string.Join("", htmlString);
        return View(mentionsLegalesModel);
  }

View:

@model MentionsLegalesModel

@Html.Raw(Model.Content)

Also you could try the Partial view suggested on the above first link

Sign up to request clarification or add additional context in comments.

3 Comments

Thank you, I had figured out the static files middleware part but I missed the Redirect method. However, I don't know how I could inject the static html in my View using this. I've looked into VirtualFileResult class but I don't quite understand how it works.
@BlackMushroom , check my updated . The VirtualFileResult class needs the virtual path to the file which is in the wwwroot , you could refer to exceptionnotfound.net/asp-net-core-demystified-action-results
As I feared, the method GetStaticFile() is not working because System.IO.File.ReadAllLines expects a "real" physical file path, not the virtual path defined by static files middleware. The only way I can think of is to use a HttpClient to download the file, but that seems odd because the file is on the same server. Thanks for the link anyway, that's a good one :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.