以编程方式从 Azure Blob 存储连接字符串中提取属性

问题描述 投票:0回答:5

给定一个 Blob 存储连接字符串,例如:

DefaultEndpointsProtocol=https;AccountName=foo;AccountKey=bar;EndpointSuffix=core.windows.net

是否有可以转换/反序列化的已知 Microsoft 对象?我不想实际解析该字符串,但我需要从整个连接字符串中提取 AccountName 和 AccountKey,我将其作为字符串。

预防可能出现的“你为什么要这样做?”问题...我有一个现有的类,需要将连接字符串作为字符串注入。为了避免破坏性的变化,我无法改变它。但我确实需要在此类中添加一些需要 AccountName 和 AccountKey 作为单独项目的方法。

谢谢!

c# azure azure-blob-storage
5个回答
9
投票

如果安装

Microsoft.Azure.Storage.Common
,您可以通过编程方式提取连接字符串的几个位,而无需自己解析连接字符串。

例如(实际信息被混淆):

using System;
using Microsoft.Azure.Storage;

namespace dotnet_connectionstring
{
    class Program
    {
        static void Main(string[] args)
        {
            CloudStorageAccount storageAccount = CloudStorageAccount.Parse("DefaultEndpointsProtocol=https;AccountName=youraccount;AccountKey=yourkey==;EndpointSuffix=core.windows.net");
            Console.WriteLine(storageAccount.BlobEndpoint);
            Console.WriteLine("---");
            Console.WriteLine(storageAccount.BlobStorageUri);
            Console.WriteLine("---");
            Console.WriteLine(storageAccount.Credentials.AccountName);
            Console.WriteLine("---");
            Console.WriteLine(storageAccount.Credentials.ExportBase64EncodedKey());
        }
    }
}

这给出了类似的输出:

https://youraccount.blob.core.windows.net/
---
主要 = 'https://youraccount.blob.core.windows.net/';次要 = 'https://youraccount-secondary.blob.core.windows.net/'
---
你的帐户
---
你的钥匙==

5
投票

据我所知,没有任何类可以做到这一点,但将其更改为字典并不难。下面的例子。

        string connString = "DefaultEndpointsProtocol=https;AccountName=foo;AccountKey=bar;EndpointSuffix=core.windows.net";

        var connStringArray = connString.Split(';');

        var dictionary = new Dictionary<string, string>();

        foreach (var item in connStringArray)
        {
            var itemKeyValue = item.Split('=');
            dictionary.Add(itemKeyValue[0], itemKeyValue[1]);
        }

然后您可以使用它访问您需要的值。

dictionary["AccountName"]
dictionary["AccountKey"]

2
投票

@David Makogon 的答案当然是最优雅的,但包

Microsoft.Azure.Storage.Common
已被弃用(如评论中所述)。根据@Patrick Mcvay 的回答(这只是有点错误,因为连接字符串值中可能有“=”),解析连接字符串的一种简单方法是:

var parsedConnectionString = new Dictionary<string, string>();
foreach (var item in ConnectionString.Split(';'))
{
    var idx = item.IndexOf('=');
    parsedConnectionString[item.Substring(0, idx)] =
        item.Substring(idx + 1, item.Length - idx - 1);
}

1
投票

为此,我们从

CloudStorageAccount
组件中获得了
Microsoft.Azure.Storage
类型。

CloudStorageAccount sa = CloudStorageAccount.Parse(connString);

0
投票

Azure.Storage.Common
确实有一个用于解析连接字符串的内部类,称为
StorageConnectionString
。它有一个名为
Parse
的公共静态方法,它接受字符串 connectionSting 作为输入:

https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/storage/Azure.Storage.Common/src/Shared/StorageConnectionString.cs#L238

我不知道他们为什么将其设置为内部,因为能够直接调用它会非常有用,但是如果我们深入研究逻辑,我们会发现他们像这样解析字符串:

/// <summary>
/// Tokenizes input and stores name value pairs.
/// </summary>
/// <param name="connectionString">The string to parse.</param>
/// <param name="error">Error reporting delegate.</param>
/// <returns>Tokenized collection.</returns>
private static IDictionary<string, string> ParseStringIntoSettings(string connectionString, Action<string> error)
{
    IDictionary<string, string> settings = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
    var splitted = connectionString.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);

    foreach (var nameValue in splitted)
    {
        var splittedNameValue = nameValue.Split(new char[] { '=' }, 2);

        if (splittedNameValue.Length != 2)
        {
            error("Settings must be of the form \"name=value\".");
            return null;
        }

        if (settings.ContainsKey(splittedNameValue[0]))
        {
            error(string.Format(CultureInfo.InvariantCulture, "Duplicate setting '{0}' found.", splittedNameValue[0]));
            return null;
        }

        settings.Add(splittedNameValue[0], splittedNameValue[1]);
    }

    return settings;
}
© www.soinside.com 2019 - 2024. All rights reserved.