【问题标题】:Images are not displayed after publishing the bot with continuous deployment使用持续部署发布机器人后不显示图像
【发布时间】:2019-05-17 07:11:31
【问题描述】:

我使用 Bot Framework 开发了一个机器人。当我在 Bot Framework Emulator 上本地运行它时,它会显示图像。但是在通过创建私有 GitHub 存储库将其发布到 Azure 后,没有显示任何图像。我正在使用 Direct-Line API 3.0。可能是什么原因?

就像,这是我的项目的树视图。图片文件夹位于 Content Root 中。

我正在使用以下静态方法来检索图像路径。

public static string CreateImagePath(string filename)
    {
        return Path.Combine(TempData.HostingEnvironment?.ContentRootPath, "images", $"{filename}");
    }

然后将其转换为 Uri,并将其分配给自适应卡片的图像。这是代码sn-p。

(AdaptiveCardFactory.CreateAdaptiveElement(card, "image") as AdaptiveImage).Url =
            new Uri(PathFactory.CreateImagePath("welcome_card_image.png"));

CreateAdaptiveElement 定义为:

public static AdaptiveElement CreateAdaptiveElement(AdaptiveCard card, string adaptiveElementId)
    {
        return card.Body.Find(ae => ae.Id == adaptiveElementId);
    }

这是我在本地运行机器人时返回的 Uri。它工作正常。

file:///C:/Users/Husai/source/repos/PanjaSahibBot/images/welcome_card_image.png

这是发布后返回的内容。

file:///D:/home/site/wwwroot/images/welcome_card_image.png

而且,它不起作用。

这是最新的命令日志。

    Command: "D:\home\site\deployments\tools\deploy.cmd"
Handling ASP.NET Core Web Application deployment.
  Restoring packages for D:\home\site\repository\GurdwaraBot.csproj...
  Generating MSBuild file D:\home\site\repository\obj\GurdwaraBot.csproj.nuget.g.props.
  Generating MSBuild file D:\home\site\repository\obj\GurdwaraBot.csproj.nuget.g.targets.
  Restore completed in 5.02 sec for D:\home\site\repository\GurdwaraBot.csproj.
Microsoft (R) Build Engine version 15.9.20+g88f5fadfbe for .NET Core
Copyright (C) Microsoft Corporation. All rights reserved.

  Restore completed in 1.41 sec for D:\home\site\repository\GurdwaraBot.csproj.
  GurdwaraBot -> D:\home\site\repository\bin\Release\netcoreapp2.2\GurdwaraBot.dll
  GurdwaraBot -> D:\local\Temp\8d6da8df6d390f3\
Creating app_offline.htm
KuduSync.NET from: 'D:\local\Temp\8d6da8df6d390f3' to: 'D:\home\site\wwwroot'
Copying file: 'GurdwaraBot.deps.json'
Copying file: 'GurdwaraBot.dll'
Copying file: 'GurdwaraBot.pdb'
Copying file: 'GurdwaraBot.runtimeconfig.json'
Copying file: 'images\01d.png'
Copying file: 'images\01n.png'
Copying file: 'images\02d.png'
Copying file: 'images\02n.png'
Copying file: 'images\03d.png'
Copying file: 'images\03n.png'
Copying file: 'images\04d.png'
Copying file: 'images\04n.png'
Copying file: 'images\09d.png'
Copying file: 'images\09n.png'
Copying file: 'images\1.jpg'
Copying file: 'images\10.jpg'
Copying file: 'images\10d.png'
Copying file: 'images\10n.png'
Copying file: 'images\11d.png'
Copying file: 'images\11n.png'
Copying file: 'images\13d.png'
Copying file: 'images\13n.png'
Copying file: 'images\2.jpg'
Copying file: 'images\3.jpg'
Copying file: 'images\4.jpg'
Copying file: 'images\5.jpg'
Copying file: 'images\50d.png'
Copying file: 'images\50n.png'
Copying file: 'images\6.jpg'
Copying file: 'images\7.jpg'
Copying file: 'images\8.jpg'
Copying file: 'images\9.jpg'
Copying file: 'images\bill.png'
Copying file: 'images\feedback.png'
Copying file: 'images\Festivals.jpg'
Copying file: 'images\festivals_bandi_chhor_divas.jpg'
Copying file: 'images\festivals_gurpurab.jpeg'
Copying file: 'images\festivals_hola_mohalla.jpg'
Copying file: 'images\festivals_maghi.jpg'
Copying file: 'images\festivals_martyrdom_of_guru_arjan.jpg'
Copying file: 'images\festivals_parkash_utsav_dasveh_patshah.jpg'
Copying file: 'images\festivals_vaisakhi.jpg'
Copying file: 'images\menu_card_image.png'
Copying file: 'images\panja_thumbnail_1.png'
Copying file: 'images\panja_thumbnail_2.png'
Copying file: 'images\panja_thumbnail_3.png'
Copying file: 'images\pof_guest_hotel.jpg'
Copying file: 'images\question.png'
Omitting next output lines...
Finished successfully.

这是我所期待的。 Locally executed 而且,这就是我通过 DirectLine 得到的!! Actual result

这是我的welcome_card.json 的内容

    {
  "type": "AdaptiveCard",
  "body": [
    {
      "type": "Image",
      "id": "image",
      "horizontalAlignment": "Center",
      "style": "Person",
      "url": "",
      "size": "Medium"
    },
    {
      "type": "TextBlock",
      "horizontalAlignment": "Center",
      "size": "Medium",
      "weight": "Bolder",
      "color": "Accent",
      "text": "Welcome to Gurdwara Bot",
      "wrap": true
    },
    {
      "type": "TextBlock",
      "horizontalAlignment": "Left",
      "text": "Hi there! I'm the Sri Panja Sahib's support bot. What can I help you with today? Just so you know, you can enter **MENU** anytime you want to go back to the options below, or just go ahead type your query.",
      "wrap": true
    }
  ],
  "actions": [
    {
      "type": "Action.Submit",
      "title": "Get an Overview",
      "data": {
        "dataId": "overview"
      }
    },
    {
      "type": "Action.Submit",
      "title": "Ask a Question",
      "data": {
        "dataId": "question"
      }
    },
    {
      "type": "Action.Submit",
      "title": "Book a Room",
      "data": {
        "dataId": "room"
      }
    },
    {
      "type": "Action.Submit",
      "title": "Give a Feedback",
      "data": {
        "dataId": "feedback"
      }
    }
  ],
  "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
  "version": "1.0",
  "speak": "Hi there! I'm the Sri Panja Sahib's support bot. What can I help you with today? Just so you know, you can enter **MENU** anytime you want to go back to the options below, or just go ahead type your query."
}

我已经定义了 AdaptiveCardFactory 来操作卡片。

public class AdaptiveCardFactory
{
    public static AdaptiveCard CreateAdaptiveCard(string path)
    {
        try
        {
            var adaptiveCardJson = File.ReadAllText(path);
            AdaptiveCardParseResult result = AdaptiveCard.FromJson(adaptiveCardJson);
             return result.Card;
        }
        catch (AdaptiveSerializationException)
        {
            throw;
        }
    }

    public static Attachment CreateAdaptiveCardAttachment(AdaptiveCard card)
    {
        return new Attachment
        {
            ContentType = "application/vnd.microsoft.card.adaptive",
            Content = card,
        };
    }

    public static AdaptiveElement CreateAdaptiveElement(AdaptiveCard card, string adaptiveElementId)
    {
        return card.Body.Find(ae => ae.Id == adaptiveElementId);
    }
}

【问题讨论】:

  • 您是否检查了图片是否已发布?您确定发布时的路径吗?您可以使用 Kudu 检查文件是否部署在您的 Web App 上
  • @NicolasR,是的,图像已发布,我确定路径。此外,所有图像都部署在我的 Web 应用程序上。
  • 您能否添加有关您的实现的更多详细信息(关于您如何使用您创建的这个 Uri)?
  • @NicolasR 是的,当然!!
  • @NicolasR 可能是斜线的问题吗?查看日志,它是“images\”,但在返回的 uri 中,它是“images/”。

标签: github continuous-integration botframework azure-web-app-service wwwroot


【解决方案1】:

TL;DR;

您必须为 AdaptiveCards 中显示的项目提供公共 URL,而不是本地项目。它与模拟器一起在本地工作,因为...您在本地,并且模拟器可以访问您的本地文件,因此它可以理解具有本地位置的文件(C:\...D:\... 文件)。

所以改变你的路径,让它使用你的子域:你可以在这里做,例如使用配置变量而不是TempData.HostingEnvironment?.ContentRootPath

public static string CreateImagePath(string filename)
{
    return Path.Combine(TempData.HostingEnvironment?.ContentRootPath, "images", $"{filename}");
}

详情:

AdaptiveCard item 在 bot 消息中作为附件传递,内部的所有内容都由客户端(通道)渲染,因此它只能渲染从外部“可见”的内容。

在此处查看我的演示:我使用了一张带有 2 张图片的 ImageSet 的卡片:一张带有 Web 上的 URL,另一张带有类似您的 URL 构建。

本地:两个图像都可以。

已发布:仅显示第一张图片

如果您查看右侧的 Inspector,很明显您必须更改构建图像 Url 的方式。

您还可以通过右键单击图像所在的区域来查看已部署的网络聊天,您将找到一个带有 D:\... 路径的链接

代码修复

1st,将您的images 文件夹移动到您的项目的wwwroot 文件夹中。然后您可以执行以下操作:

public string CreateImagePath(string filename)
{
    if (_hostingEnvironment.IsDevelopment())
    {
        return Path.Combine(TempData.HostingEnvironment?.ContentRootPath, "wwwroot", "images", $"{filename}");
    }
    else
    {
        var targetUri = new Uri(new Uri($"https://{Environment.ExpandEnvironmentVariables("%WEBSITE_SITE_NAME%")}.azurewebsites.net"), Path.Combine("images", $"{filename}"));
        return targetUri.ToString();
    }
}

【讨论】:

  • 是的,我使用了很多网络上的图片,它们像您的一样显示在卡片中,即使在发布之后也是如此。但我用来填充卡片的大多数图像都在“图像”文件夹中。我想用这些图像渲染我的卡片。没有其他方法可以实现吗?
  • 当您在发布时复制它们时,它们是可用的!你只需要改用«yourBot.azurewebsites.net/images/filename.jpg»
  • 您可以通过多种方式做到这一点,例如看这个线程stackoverflow.com/questions/23207147/…
  • 我添加了一个代码结论,帮助您在本地和部署的uri之间进行切换
  • 哇!它就像魔术一样......非常感谢尼古拉斯罗伯特。 ???
猜你喜欢
  • 2015-10-09
  • 1970-01-01
  • 1970-01-01
  • 2015-02-21
  • 2016-08-31
  • 1970-01-01
  • 2016-04-11
  • 1970-01-01
  • 2019-11-06
相关资源
最近更新 更多