C# 在HeroCard的CardImage中添加图像URL

C# 在HeroCard的CardImage中添加图像URL,c#,botframework,facebook-messenger-bot,C#,Botframework,Facebook Messenger Bot,我正在制作一张HeroCard,其中包含必须显示图像的CardImage。直到现在我还在用 HeroCard hcBody = new HeroCard { Text = "IMG", Images = new List<CardImage> { new CardImage(url: $"https://www.example.com/Pictures/" + picNo + ".jpg") }, Buttons = new List<C

我正在制作一张HeroCard,其中包含必须显示图像的CardImage。直到现在我还在用

HeroCard hcBody = new HeroCard
{
    Text = "IMG",
    Images = new List<CardImage> { 
       new CardImage(url: $"https://www.example.com/Pictures/" + picNo + ".jpg") },
    Buttons = new List<CardAction> { 
       new CardAction(ActionTypes.ImBack, "SELECT"+picNo , value: picvalue) },
 };
 msg.Attachments.Add(hcBody.ToAttachment());
并将CardImage url修改为

Images = new List<CardImage> { new CardImage(url: picPath+ picNo + ".jpg") }
Images=newlist{newcardimage(url:picPath+picNo+“.jpg”)}

使用记录器,我看到构建的路径是正确的,HeroCard显示出来,但图像丢失。因此,如果我想在服务器上使用项目的路径,我想需要以不同的方式创建CardImage的URL?

您需要确保创建CardImage时使用的每个URL都是有效的绝对HTTPS URL(否则它在Facebook中无法工作)。请记住,这些URL将在客户端设备中呈现,因此它们必须可以从任何地方访问

首先,如果要在bot webapp中托管图像,请确保它们位于wwwroot文件夹中

其次,我建议在appsettings.json中设置一个基本url,用于承载图像(例如)。
现在,它可以是您的bot webapp域,以后它可以是blob存储或其他任何形式。
然后用一个方法创建一个简单的类,该方法接收图像名称并在其前面加上此设置,这样就不需要在每个对话框中重复相同的代码。例如:

appsettings.json

{
  "ImagesBaseUrl": "https://www.example.com/Pictures/",
  "..."
}
服务

public interface IImageService
{
    string GetImagePath(string imageName);
}

public class ImageService : IImageService
{
    private readonly string _baseUrl;

    public ImageService(IConfiguration configuration)
    {
        _baseUrl = configuration?.GetValue<string>("ImagesBaseUrl") ?? throw new ArgumentNullException(nameof(configuration));
    }

    // probably improve this further with / checking, handle extensions, etc
    public string GetImagePath(string imageName)
    {
        return string.Concat(_baseUrl, imageName);
    }
}
公共接口IImageService
{
字符串GetImagePath(字符串imageName);
}
公共类ImageService:IImageService
{
私有只读字符串\u baseUrl;
公共图像服务(IConfiguration配置)
{
_baseUrl=configuration?.GetValue(“ImagesBaseUrl”)??抛出新的ArgumentNullException(nameof(configuration));
}
//可能会通过/检查、处理扩展等进一步改进这一点
公共字符串GetImagePath(字符串imageName)
{
返回string.Concat(_baseUrl,imageName);
}
}
然后将
IImageService
注入你的机器人/对话框或任何你需要构建英雄卡的地方

编辑:如果你真的想获得你的应用程序运行的服务器绝对路径,你必须使用类似

但是,如果您使用的是BotFrameworkV4,那么您可能使用的是NetCore,因此您必须根据您的NetCore版本来使用它。您最好将
IHostingEnvironment
/
IWebHostEnvironment
注入到一个地方,就像我上面提到的服务一样。想象一下,他们将来会再次更改它,而您必须在许多对话框中重命名它


我仍然更喜欢使用appsettings版本,因为它更通用,以备将来需要更改(不必更改代码和重新构建应用)。

这里有很多混淆。听起来您想继续从公共URL加载图像,但希望新URL指向部署应用程序的同一域。出于某种原因,你已经在你的应用程序设置中添加了新的URL,但是你也可以用旧的URL轻松地完成这项工作,所以整个配置加载只是一个转移视线的事情,对吗?你说“构建路径”是正确的,但那是什么路径?您是否尝试将路径输入浏览器以查看该URL是否确实返回图像?一年半前您提出此问题时,您似乎接受了答案:@KyleDelaney我必须将更改为~/Pictures/。URL将更改,因此我无法在代码中再使用它。我需要添加通过根文件夹。我还试着回答了我以前问过的问题,但这次运气不好。记住,bot框架已经更新。我不知道关于卡片图像的构建是否有任何改变。我看到您在下面也得到了一个很好的答案,但听起来您仍然有困难。你愿意将图像嵌入卡中而不是链接到卡上吗?我使用了一个有效的HTTPS URL,它工作正常,但我不能保持这种逻辑。该软件将被移动到另一个领域,所以我需要一个路径,将不需要任何未来的修改。这就是为什么我试图实现类似~/Pictures/的功能,这样我将使用根路径,它将始终是相同的。这就是为什么我建议将它放在appsettings中。您可以在运行时更改它,而无需重新生成代码。像~/Pictures/这样的东西本身无法工作,此路径将在客户端与bot对话的域中获取,而不是在bot服务器中获取。它可以是Facebook、Skype或在另一个域中使用direct line的网络聊天。在将活动附件发送到对话之前,您需要在活动附件中包含一个绝对URL。我将更新关于如何以编程方式获取绝对路径的答案。
public interface IImageService
{
    string GetImagePath(string imageName);
}

public class ImageService : IImageService
{
    private readonly string _baseUrl;

    public ImageService(IConfiguration configuration)
    {
        _baseUrl = configuration?.GetValue<string>("ImagesBaseUrl") ?? throw new ArgumentNullException(nameof(configuration));
    }

    // probably improve this further with / checking, handle extensions, etc
    public string GetImagePath(string imageName)
    {
        return string.Concat(_baseUrl, imageName);
    }
}