System.ArgumentException: 'Should specify SharedAccessKeyName'

System.ArgumentException: 'Should specify SharedAccessKeyName'

我在创建预配客户端时从 Azure IoT 预配服务收到此错误。

System.ArgumentException: 'Should specify SharedAccessKeyName'

我从 Portal 复制了连接字符串,有什么问题吗?

using System;
using System.IO;
using System.Reflection;
using System.Security.Cryptography.X509Certificates;
using System.Threading.Tasks;
using Microsoft.Azure.Devices.Provisioning.Service;

namespace EnrollmentApp
{
    class Program
    {
        private static string ProvisioningConnectionString = "HostName=happybeerhub-us.azure-devices.net;DeviceId=test-device-01;SharedAccessKey=tawpddfqUt3EHZg9a5tUzQ5fjros7zMhKsZbmuXzwXE=";
        private static string EnrollmentGroupId = "test";
        private static string X509RootCertPath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), @"key.pfx");        

        static void Main(string[] args)
        {
            RunSample().GetAwaiter().GetResult();
            Console.WriteLine("\nHit <Enter> to exit ...");
            Console.ReadLine();
        }

        public static async Task RunSample()
        {
            Console.WriteLine("Starting sample...");

            using (ProvisioningServiceClient provisioningServiceClient =
                    ProvisioningServiceClient.CreateFromConnectionString(ProvisioningConnectionString))
            {
                #region Create a new enrollmentGroup config
                Console.WriteLine("\nCreating a new enrollmentGroup...");
                var certificate = new X509Certificate2(X509RootCertPath);
                Attestation attestation = X509Attestation.CreateFromRootCertificates(certificate);
                EnrollmentGroup enrollmentGroup =
                        new EnrollmentGroup(
                                EnrollmentGroupId,
                                attestation)
                        {
                            ProvisioningStatus = ProvisioningStatus.Enabled
                        };
                Console.WriteLine(enrollmentGroup);
                #endregion

                #region Create the enrollmentGroup
                Console.WriteLine("\nAdding new enrollmentGroup...");
                EnrollmentGroup enrollmentGroupResult =
                    await provisioningServiceClient.CreateOrUpdateEnrollmentGroupAsync(enrollmentGroup).ConfigureAwait(false);
                Console.WriteLine("\nEnrollmentGroup created with success.");
                Console.WriteLine(enrollmentGroupResult);
                #endregion

            }
        }
    }
}

好吧,你错过了 SharedAccessKeyName 所以验证会尝试检查它,因为在你的情况下它是空的,你会得到异常。

如您在 ServiceConnectionStringBuilder.cs 中所见,正确的连接字符串格式为

/// A valid connection string shall be in the following format:
/// <code>
/// HostName=[ServiceName];SharedAccessKeyName=[keyName];SharedAccessKey=[Key]
/// </code>

同样在第 128 行,您可以看到引发异常的检查:

        if (string.IsNullOrWhiteSpace(SharedAccessKeyName))
        {
            throw new ArgumentException("Should specify SharedAccessKeyName");
        }

现在您可能认为 ServiceConnectionStringBuilder.cs 未被您的代码使用,但调用 ProvisioningServiceClient.CreateFromConnectionString 会创建一个新的 ProvisioningServiceClient 实例,该实例又会调用 ServiceConnectionStringBuilder.Parse()。 有关详细信息,请参阅第 82、113 和 123 行中的 ProvisioningServiceClient.cs

解决方案:

要解决此问题,您必须提供一个 SharedAccessKeyName。您还应该考虑为此使用 IotHubConnectionStringBuilder,它在构建连接字符串时已经检查了您的属性。

提问者根据这篇博客posthere指出键名是deviceId。因此,解决方案是使用 SharedAccessKeyname=xx 而不是 DeviceId=xx.