4

I have the following configuration:

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        app.UseDefaultFiles();

        app.UseFileServer(new FileServerOptions
        {
            FileProvider = new EmbeddedFileProvider(typeof(Startup).Assembly, typeof(Startup).Namespace + ".WebApp"),
            RequestPath = string.Empty
        });

        app.UseCors("CorsPolicy");

        app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "angular",
                defaults: new {controller = "Angular", action = "Index"},
                template: "{*url}");
        });
    }

My Angular project files are in the namespace MyNamespace.WebApp.

My AngularController and Startup classes are in the namespace MyNamespace

When I don't use MVC and access http://localhost:8000 it loads the index.html file in the WebApp folder. Now for all other requests (for example /action) I have mapped it to the AngularController, which looks as follows:

public class AngularController : Controller
{
    public IActionResult Index() {
        return View("/index.html");
    }
}

I have debugged and verified that the request does come to AngularController.Index() and returns View("/index.html"). But after that I get a 500 Error. I'm guessing because it cannot find the view file.

How do I let MVC know to fetch the index.html file from the embedded files?

I've tried the following:

return View("~/index.html");
return View("index.html");
return View("~/../index.html");
return View("../index.html");
return View("~/WebApp/index.html");
return View("WebApp/index.html");

None of these work. Probably I've missed a step?

2 Answers 2

3

In this example, I've tried to create an HTML file with the name htmlpage.html in the path Views/Home/htmlpage.html.

In the file Index.cshtml (path: Views/Home/Index.cshtml):

@using Microsoft.AspNetCore.Hosting
@using System.IO
@inject IHostingEnvironment environment
@{ 
    string htmlPath = "Views/Home/htmlpage.html";
}

@Html.Raw(File.ReadAllText(System.IO.Path.Combine(environment.ContentRootPath, htmlPath)))

In the file htmlpage.html:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>bar</title>
</head>
<body>
    <h3>foo</h3>
</body>
</html>

Test:

1


This way doesn't require: app.UseDefaultFiles(); and app.UseFileServer(...);

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

1 Comment

Sorry, but this answer is also for physical files present in the bin folder and not for "Embedded Files"
1

My solution was to configure a controller that would use an EmbeddedFileProvider and fetch the contents of the embedded file as follows:

public AngularController: Controller
{
    private IAppSettings appSettings;

    public AngularController(IAppSettings appSettings)
    {
        this.appSettings = appSettings;
    }

    public IActionResult Index()
    {
        var fileProvider = new EmbeddedFileProvider(this.appSettings.WebAssembly, this.appSettings.WebNamespace);
        var contents = this.fileProvider.GetDirectoryContents(string.Empty);

        IFileInfo index = null;
        foreach (var file in contents)
        {
            if (file.Name.Equals("index.html"))
            {
                index = file;
                break;
            }
        }

        if (index == null)
        {
            throw new Exception("'index.html' not found");
        }

        var reader = new StreamReader(index.CreateReadStream());
        var text = reader.ReadToEnd();
        return this.Content(text, "text/html");
    }
}

The Assembly and Namespace of the embedded files are provided using dependency injection to make it more generic. You could also hard code it into the controller.

Comments

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.