首页 > 解决方案 > 多个环境 Azure Blob 存储连接字符串似乎有冲突

问题描述

首先让我说我很难通过查询来找到这个问题的答案。我什至不知道如何简短地描述这个标题以获得正确的标题......无论如何,我已经搜索了 SO 和网络上的各个地方以获得答案,但我想出了甜甜圈。所以...

我有一个适用于三个环境分支的 API(.NET、C#):devqaprod. 我有三个 Azure 应用服务来支持这三个环境:appServDevappServQaappServPod。我还为每个环境提供了 Azure Blob 存储:blobDev, blobQa, blobProd; 每个都有一个 blob 存储容器来保存一些必要的数据,以将其提供给最终用户。此外,在生产 Blob 存储中,我有一个 Blob 容器,旨在在所有三个程序环境中共享一组特定的文件,我们称之为mySharedStorage. 此容器不存在于blobDevblobQa

所以 blob 容器结构是这样的:

blobDev
  -myDevStorage

blobQa
  -myQaStorage

blobProd
  -myProdStorage
  -mySharedStorage

Blob 容器已在my[environment]Storage所有环境中复制数据,而 Dev 和 Qa 仅拥有一小部分 prod 数据。我们必须这样做以将数据与 prod 分开以进行测试。mySharedStorage具有所有三个都需要的环境不敏感数据(仅用于将 .pdf 文件下载给用户)。

在 Registry.cs 和 Web.Config 中,我设置了连接字符串以根据环境访问适当的存储。在 Web.Config 中,我有这些行,值将根据环境进行转换:

  <add key="MyAzureConnectionString" value="" />
  <add key="MyAzureSharedConnectionString" value="" />

最终MyAzureSharedConnectionString获得正确的连接字符串blobProd > mySharedStorage,而MyAzureConnectionString获得相应环境连接字符串的字符串(例如 QA 获得blobQA > myQaStorage连接字符串);

但是,我无法让 Dev 和 QA 环境访问mySharedStorage. 当我单步执行代码时似乎发生的事情MyAzureConnectionString似乎覆盖了MyAzureSharedConnectionString. 基本上在 Dev 和 QA 中,程序正在寻找mySharedStorage不存在的错误环境中的容器。然而,在产品中,这一切都很好......因为它存在于那里!

为了测试所有这些,我硬编码了两个连接字符串,其中 shared 始终是正确的生产共享存储,另一个我在三个环境之间进行更改。开发和质量保证失败,而产品总是有效。

我需要做什么才能让 Dev 和 QA 指向正确的共享存储?

编辑:根据要求提供更多信息。这都使用BlobStorageUtility带有以下构造函数的 a :

public BlobStorageUtility(
  string blobContainerName,
  string storageConnectionString,
  bool isPublic = true)
{
  this._storageConnectionString = storageConnectionString;
  this.SetBlobContainer(blobContainerName, isPublic);
}

在 Registry.cs 文件中:

For<IBlobStorageUtility>().Use<BlobStorageUtility>()
    .Named("prodBlobStorageUtility")
    .Ctor<string>("blobContainerName").Is(settings["ProdBlobContainerName"])
    .Ctor<string>("storageConnectionString").Is(settings["AzureStorageConnectionString"])
    .Ctor<bool>("isPublic").Is(true);

For<IBlobStorageUtility>().Use<BlobStorageUtility>()
    .Named("sharedBlobStorageUtility")
    .Ctor<string>("blobContainerName").Is(settings["SharedBlobContainerName"])
    .Ctor<string>("storageConnectionString").Is(settings["AzureSharedStorageConnectionString"])
    .Ctor<bool>("isPublic").Is(true);

并且还 int Web.Config 以获取注册表的值...

    <add key="ProdBlobContainerName" value="prodWebSite" />
    <add key="SharedBlobContainerName" value="sharedSite-files" />

正在访问文件的生产代码

public class SharedFileService : ISharedFileService
{
    private readonly IBlobStorageUtility _blobStorageUtility;
    private readonly IFileDetailService _fileDetailService

    public MsdsService(IFileDetailService fileDetailService, IBlobStorageUtility blobStorageUtility)
    {
        _blobStorageUtility = blobStorageUtility;
        _fileDetailService = fileDetailService;
    }

    ...

    public FileDto GetFile (int? fileId, string fileName)
    {
        var filename = _fileDetailService.GetfileInfo(fileId, fileName).FileName;
        var contentType = GetContentType(filename); //gets the type of file, in this case a pdf

        // This next line is where I can see the blobStorageUtility is pointed to the wrong environment, not shared
        _blobStorageUtility.SetBlobContainer(ConfigurationManager.AppSettings["SharedBlobContainerName"]);
        // so then this line fails with a null reference... 
        var blobReference = _blobStorageUtility.GetBlockBlobReference($"{filename}");

        if (blobReference.Exists())
        {
            blobReference.FetchAttributes();

            var byteArr = new byte[blobReference.Properties.Length];
            blobReference.DownloadToByteArray(byteArr, 0);

            return new FileDto() { File = byteArr, ContentType = contentType };
        }
        else
        {
            return null;
        }
    }
}

编辑:作为此问题的解决方法,我们只是在所有三个环境中复制了共享存储,只有一小部分数据用于测试。这并不理想并且违背了共享存储的目的。但是,它完成了任务。我仍然很想找到一个解决方案,让我们可以从任何环境访问 Prod 共享存储,同时保持与 Dev 和 QA 存储的连接。

标签: asp.netazureazure-blob-storage

解决方案


推荐阅读