【问题标题】:How to return an embedded static html file from an Asp.Net Core Controller?如何从 Asp.Net 核心控制器返回嵌入式静态 html 文件?
【发布时间】:2018-11-16 09:30:28
【问题描述】:

我有以下配置:

    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}");
        });
    }

我的 Angular 项目文件位于命名空间 MyNamespace.WebApp。

我的 AngularController 和 Startup 类位于命名空间 MyNamespace

当我不使用 MVC 并访问 http://localhost:8000 时,它会在 WebApp 文件夹中加载 index.html 文件。现在对于所有其他请求(例如/action),我已将其映射到AngularController,如下所示:

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

我已调试并验证该请求确实到达AngularController.Index() 并返回View("/index.html")。但在那之后我得到一个 500 错误。我猜是因为它找不到视图文件。

如何让 MVC 知道从嵌入文件中获取 index.html 文件?

我尝试了以下方法:

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");

这些都不起作用。可能是我漏了一步?

【问题讨论】:

    标签: c# angular asp.net-core asp.net-core-mvc


    【解决方案1】:

    在此示例中,我尝试在路径 Views/Home/htmlpage.html 中创建名称为 htmlpage.html 的 HTML 文件。

    在文件Index.cshtml(路径: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)))
    

    在文件htmlpage.html:

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

    测试:


    这种方式不需要:app.UseDefaultFiles(); 和 app.UseFileServer(...);

    【讨论】:

    • 对不起,这个答案也适用于 bin 文件夹中的物理文件,而不适用于“嵌入式文件”
    【解决方案2】:

    我的解决方案是配置一个控制器,该控制器将使用 EmbeddedFileProvider 并获取嵌入文件的内容,如下所示:

    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");
        }
    }
    

    嵌入文件的Assembly 和Namespace 是使用依赖注入提供的,以使其更通用。您也可以将其硬编码到控制器中。

    【讨论】:

      猜你喜欢
      • 2020-04-09
      • 2017-07-29
      • 1970-01-01
      • 2020-05-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-20
      • 2019-06-08
      相关资源
      最近更新 更多