我正在使用Web Api和Angular JS开发单页应用程序。我想抓住一个伟大的水疗应用程序的所有最佳实践。
我想知道这是将Web Api项目作为单独项目托管的最佳做法,或者只是与您的水疗中心一起包含在同一项目中。
谢谢
答案 0 :(得分:10)
我认为最好的办法是将SPA放到一个单独的项目中,甚至更好地建立一个不同的存储库,因为它更灵活,支持许多不同的开发/部署方案,特别是当您的项目变得更大时。
我个人开始使用混合文件方法,并在项目超出Todos示例的大小几天后转移到单独的Repos方法。
拥有单独项目/回购的一些优点是:
另一方面,我无法想到将SPA作为WebApi的子文件夹的任何优点,除非您希望将复杂性降至最低限度的非常小的项目。
答案 1 :(得分:1)
当谈到从 .NET API 托管 SPA 时,有三种扩展方法可以完成所有繁重的工作(从 .NET Core 2.x 开始,在 .NET 5 中仍然如此):
index.html
) 并将所有请求重定向到那里。index.html
)下提供除 wwwroot
之外的静态文件。如果没有此方法,Kestrel 将返回 index.html 以响应对静态内容的所有请求。wwwroot
下,则需要它。要从 wwwroot
托管 SPA,您只需要 UseSpa
和 UseStaticFiles
方法。
不要忘记两件重要的事情:
因此您在 Configure
中的 Startup.cs
方法可能有以下添加:
// Serves other than 'index.html' files from wwwroot folder with a cache policy
app.UseStaticFiles(new StaticFileOptions
{
OnPrepareResponse = ctx =>
{
var headers = ctx.Context.Response.GetTypedHeaders();
headers.CacheControl = new CacheControlHeaderValue { MaxAge = TimeSpan.FromDays(12*30) };
}
});
// Serves 'index.html' with no-cache policy and passing variables in a cookie
app.UseSpa(c => c.Options.DefaultPageStaticFileOptions = new StaticFileOptions
{
OnPrepareResponse = ctx =>
{
var response = ctx.Context.Response;
response.GetTypedHeaders().CacheControl = new CacheControlHeaderValue
{
NoCache = true,
NoStore = true,
MustRevalidate = true,
MaxAge = TimeSpan.Zero
};
// Passing a variable to SPA in a short-lived cookie
response.Cookies.Append("importantVariable", "Value", new CookieOptions { MaxAge = TimeSpan.FromSeconds(30) });
}
})
在 this blog post 中查看更多,其中还考虑了其他选项。
另请查看 this open source project at GitHub,它通过托管 SPA 并在 cookie(direct link to Startup configuration 和 reading cookies in Angular)中传递参数来实现这一点。
答案 2 :(得分:0)
我发现在WebAPI项目中包含SPA更容易。我总是将SPA代码放在一个单独的文件夹中(我总称它为“app”)并告诉WebAPI在您点击WebAPI站点的根URL时加载该文件夹中的“index.html”文件。为了提供静态文件,我将OWIN与FileSystems和StaticFiles插件一起使用。
我知道,问题不是“如何”实现它,但如果您决定使用OWIN,这可能对您有用。这段代码告诉OWIN(因此是WebAPI)在哪里查找“index.html”和静态(CSS,JS ...)文件)
builder.UseDefaultFiles(new DefaultFilesOptions()
{
RequestPath = new PathString(),
DefaultFileNames = new List<string>() { "index.html" },
FileSystem = new PhysicalFileSystem(@".\app")
});
builder.UseStaticFiles(new StaticFileOptions()
{
RequestPath = new PathString(),
FileSystem = new PhysicalFileSystem(@".\app")
});