如何从Visual Studio 2019部署Blazor服务器托管的应用程序

时间:2019-06-11 12:08:42

标签: visual-studio blazor blazor-server-side

我正在使用VS2019 Preview。 我使用最新的Blazor扩展(16.0.19227)创建了一个“服务器托管”的Blazor应用程序。这是包含3个独立项目的变体...

  • MyApp.Client
  • MyApp.Server
  • MyApp.Shared

我可以通过使MyApp。 Server 成为活动项目来进行调试,并且一切正常,但是我正努力将其发布/部署到Azure。我尝试了以下方法...

  • 在解决方案资源管理器中右键单击MyApp.Server
  • 选择“发布”
  • 通过向导创建一个新的发布配置文件
  • 将部署模式更改为“自包含”
  • 点击发布

这时在部署过程中出现错误...

  

CSC(0,0):错误CS0006:元数据文件'D:\ work \ Applications \ Web \ MyApp.Client \ bin \ Release \ netstandard2.0 \ win-x86 \ MyApp.Client.dll'   找不到

这似乎是因为Web部署配置文件中的“目标运行时” 设置为 win-x86 。客户端应用程序实际上是作为

构建的
  

“ D:\ work \ Applications \ Web \ MyApp.Client \ bin \ Release \ netstandard2.0 \ MyApp.Client.dll”

(没有附加的win-x86子文件夹),因此部署过程似乎对构建过程使用的路径做出了错误的假设。在发布对话框中无法指定空白/无关目标运行时。

是否有解决方法,或者我使用的部署方法错误?

有一些official documentation,但这不是很有帮助。

更新似乎部署使用的是Client项目的输出路径,然后仅将 netstandard2.0 {Target Runtime} 附加到其上,以便更改输出路径Client项目中的代码不足以解决此问题。

更新2 通过编辑xml删除发布配置文件中的 RuntimeIdentifier 标记只会导致部署时错误,表明空的RuntimeIdentifier与自包含的不兼容。部署。不幸的是,自包含的部署是必需的,因为Azure尚未直接托管.net core 3。

3 个答案:

答案 0 :(得分:4)

  

因为Azure尚未直接托管.net core 3。

但是确实如此。

在Azure门户中,部署后转到您的WebApp(或预先创建一个)。

转到扩展,然后单击添加[ + ]并选择ASP.NET Core 3(免费托管为x86)。

也可以转到“设置”,“常规”并启用WebSocket,默认情况下它们处于关闭状态。


临时:

请注意,Preview-6不能作为扩展使用,因此可以使用Preview-5或作为独立的部署。

答案 1 :(得分:2)

无法在评论中添加图片,所以我想在这里显示。这是我当前的发布向导。

enter image description here

只需通过新项目-> Asp.net核心Web应用程序-> blazor(托管Asp.net核心)就可以完成并发布,以确保应用程序服务正常。

答案 2 :(得分:0)

我的答案是:

  • 将发布配置文件配置为“自包含”部署模式。
  • 编辑所有.csproj文件,将<TargetFramework>...</TargetFramework>节点名称更改为<TargetFrameworks>...</TargetFrameworks>。 (另请参见:https://stackoverflow.com/a/42855070
  • 在运行时在Startup类中修复Web根文件夹路径字符串,如下所示。
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.ResponseCompression;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.FileProviders;
using Microsoft.Extensions.Hosting;
using Newtonsoft.Json.Serialization;
using System.IO;
using System.Linq;

namespace BlazorHostedOnAzure.Server
{
    public class Startup
    {
        // This method gets called by the runtime. Use this method to add services to the container.
        // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc().AddNewtonsoftJson();
            services.AddResponseCompression(opts =>
            {
                opts.MimeTypes = ResponseCompressionDefaults.MimeTypes.Concat(
                    new[] { "application/octet-stream" });
            });
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            app.UseResponseCompression();

            // ---- APPEND PART.1 BEGIN ----
            var clientBlazorWebRootPath = default(string);
            // ---- APPEND PART.1 END ----

            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
                app.UseBlazorDebugging();
            }

            // ---- APPEND PART.2 BEGIN ----
            else
            {
                if (env.WebRootPath != null)
                {
                    var pathOfIndex = Path.Combine(env.WebRootPath, "index.html");
                    var pathOfContent = Path.Combine(env.WebRootPath, "_content");
                    if (!File.Exists(pathOfIndex) && Directory.Exists(pathOfContent))
                    {
                        clientBlazorWebRootPath = Directory.GetDirectories(pathOfContent).FirstOrDefault();
                        if (clientBlazorWebRootPath != null)
                        {
                            env.WebRootPath = clientBlazorWebRootPath;
                        }
                    }
                }
            }
            // ---- APPEND PART.2 END ----

            app.UseClientSideBlazorFiles<Client.Startup>();

            app.UseRouting();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapDefaultControllerRoute();
                endpoints.MapFallbackToClientSideBlazor<Client.Startup>("index.html");
            });

            // ---- APPEND PART.3 BEGIN ----
            if (clientBlazorWebRootPath != null)
            {
                app.UseStaticFiles(new StaticFileOptions
                {
                    FileProvider = new PhysicalFileProvider(clientBlazorWebRootPath)
                });
            }
            // ---- APPEND PART.3 BEGIN ----
        }
    }
}

我在我的存储库GitHub上发布了示例代码和自述文件。