Azure SDK UnauthorizedException:放置令牌失败。 status-code: 401, status description: Unauthorized: 当KeyName为空时资源URI必须

Azure SDK UnauthorizedException: Put token failed. status-code: 401, status description: Unauthorized: When KeyName is empty the resource URI must

使用 C#,来自 Visual Studio 的 Windows 表单模板和 Microsoft Azure Client SDK

我正在尝试向 IOT 中心发送消息。我用 Virtual Pi 测试了连接字符串,它在那里工作,我可以在 Azure Shell.

中看到连接和传入消息

进口:

using System.Windows.Forms;
using Microsoft.Azure.Devices;
using Message = Microsoft.Azure.Devices.Message;
static string connectionString = "HostName=****.azure- devices.net;DeviceId=****;SharedAccessKey=*******=";
static string deviceId = "SensorTest";
static ServiceClient serviceClient;

serviceClient = ServiceClient.CreateFromConnectionString(connectionString);
SendMessageToCloud("takemystringyoupieceof***").Wait();


private static async Task SendMessageToCloud(string s)
        {
            MyData data = new MyData
            {
                Thing1 = "string",
                Thing2 = "string",
                Thing3 = 1234,
                Thing4 = "string",
                Thing5 = s
            };

            var serializeData = JsonConvert.SerializeObject(data);
            var commandMessage = new Message(Encoding.ASCII.GetBytes(serializeData));
            await serviceClient.SendAsync(deviceId, commandMessage);
        }

这会引发内部异常:

{"Put token failed. status-code: 401, status-description:
Unauthorized: When KeyName is empty the resource URI must include a device id (Value '****.azure- devices.net').."} 
System.Exception {Microsoft.Azure.Devices.Common.Exceptions.UnauthorizedException}

我需要一些帮助来理解错误消息:

对于工作代码示例,myData class:

internal class MyData
    {
        public string Thing1 { get; set; }
        public string Thing2 { get; internal set; }
        public int Thing3 { get; set; }
        public string Thing4 { get; set; }
        public string Thing5 { get; set; }

    }

您正在将 DeviceClient 连接字符串与 ServiceClient 一起使用。您在 SendMessageToCloud 中调用的 SendAsync 实际上是 Cloud to Device API。因此,根据您的意图,答案是您需要使用 DeviceClient(可以找到有用的示例 here) or you want to use an appropriate Service connection string which can be found in the Shared access policies blade for the IoTHub in the portal. Practicing least privilege, the Service key allows cloud-to-device messages (details on shared access policies can be found here