来自 C# 的 Azure BLOB 存储 REST 调用

2023-12-13

我正在尝试通过控制台应用程序与 Azure Blob 存储上的容器进行通信。我无法使用 SDK,因此 REST 是我唯一的选择。语言是 C#,带有 .NET 4.5.2。

我已经尝试过这两个代码并且都返回相同的错误

Azure Rest API 将 blob 放在 StackOverflow 上

Azure Blob 存储第 5 部分(非 StackOverflow)

The error that I receive is 400 Bad Request Error from my console application

还有其他人遇到过同样的问题并成功解决了吗?

我为几乎所有内容添加了带有 (*) 的 CORS 规则

该代码与两个链接完全相同,因此我不会在此处添加它。

    class Program
   {
    static void Main(string[] args)
    {

        UploadBlobWithRestAPI();
    }

    public static void UploadBlobWithRestAPI()
    {

        string storageKey = "ffFJwPXTqyYvRoubNQEti/aQUUMwn41BG3KDtl/yGpG4DR1eKaHRq6Bhbw==";
        string storageAccount = "xyz";
        string containerName = "notes";
        string blobName = "test567";

        string method = "PUT";
        string sampleContent = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla id euismod urna. Maecenas scelerisque dolor purus, sed ullamcorper ipsum lobortis non. Nulla est justo, sodales at venenatis a, faucibus";
        int contentLength = Encoding.UTF8.GetByteCount(sampleContent);

        string requestUri = $"https://xyz.blob.core.windows.net/notes/test567";

        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(requestUri);

        string now = DateTime.UtcNow.ToString("R");

        request.Method = method;
        request.ContentType = "text/plain; charset=UTF-8";
        request.ContentLength = contentLength;

        request.Headers.Add("x-ms-version", "2018-01-11");
        request.Headers.Add("x-ms-date", now);
        request.Headers.Add("x-ms-blob-type", "BlockBlob");
        request.Headers.Add("Authorization", AuthorizationHeader2(method, now, request, storageAccount, storageKey, containerName, blobName));

        using (Stream requestStream = request.GetRequestStream())
        {
            requestStream.Write(Encoding.UTF8.GetBytes(sampleContent), 0, contentLength);
        }

        using (HttpWebResponse resp = (HttpWebResponse)request.GetResponse())
        {
            Console.WriteLine(resp.StatusCode.ToString());
            Console.ReadKey();
        }

    }

    public static string AuthorizationHeader2(string method, string now, HttpWebRequest request, string storageAccount, 
        string storageKey, string containerName, string blobName)
    {

        string headerResource = $"x-ms-blob-type:BlockBlob\nx-ms-date:"+ DateTime.UtcNow.ToString("R") +"\nx-ms-version:2018-01-11";
        string urlResource = "/xyz/notes/test567";
        string stringToSign =  method + "\n\n\n" + request.ContentLength + 
            "\n\n" + request.ContentType +"\n\n\n\n\n\n\n" + headerResource + "\n" + urlResource;


        HMACSHA256 hmac = new HMACSHA256(Convert.FromBase64String(storageKey));
        string signature = Convert.ToBase64String(hmac.ComputeHash(Encoding.UTF8.GetBytes(stringToSign)));

        String AuthorizationHeader = String.Format("{0} {1}:{2}", "SharedKey", storageAccount, signature);
        return AuthorizationHeader;
    }


}

您的代码有两个问题:

  1. 您使用的服务版本无效。最新的存储服务 REST API 版本是2017-04-17并不是2018-01-11。更改后,您将不会收到 400 错误(但会收到 403 错误)。
  2. In your headerResource,您正在生成一个新的日期/时间值,该值与您的日期/时间值不同x-ms-date标头。因此,您将收到 403 错误。所以本质上你的代码是:

        string headerResource = $"x-ms-blob-type:BlockBlob\nx-ms-date:" + now + "\nx-ms-version:2017-04-17";
    

我做了这两个修复,之后我就可以上传数据了。

这是完整的代码:

    public static void UploadBlobWithRestAPI()
    {

        string storageKey = "ffFJwPXTqyYvRoubNQEti/aQUUMwn41BG3KDtl/yGpG4DR1eKaHRq6Bhbw==";
        string storageAccount = "xyz";
        string containerName = "notes";
        string blobName = "test567";

        string method = "PUT";
        string sampleContent = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla id euismod urna. Maecenas scelerisque dolor purus, sed ullamcorper ipsum lobortis non. Nulla est justo, sodales at venenatis a, faucibus";
        int contentLength = Encoding.UTF8.GetByteCount(sampleContent);

        string requestUri = $"https://xyz.blob.core.windows.net/notes/test567";

        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(requestUri);

        string now = DateTime.UtcNow.ToString("R");

        request.Method = method;
        request.ContentType = "text/plain; charset=UTF-8";
        request.ContentLength = contentLength;

        request.Headers.Add("x-ms-version", "2017-04-17");
        request.Headers.Add("x-ms-date", now);
        request.Headers.Add("x-ms-blob-type", "BlockBlob");
        request.Headers.Add("Authorization", AuthorizationHeader2(method, now, request, storageAccount, storageKey, containerName, blobName));

        using (Stream requestStream = request.GetRequestStream())
        {
            requestStream.Write(Encoding.UTF8.GetBytes(sampleContent), 0, contentLength);
        }

        using (HttpWebResponse resp = (HttpWebResponse)request.GetResponse())
        {
            Console.WriteLine(resp.StatusCode.ToString());
            Console.ReadKey();
        }

    }

    public static string AuthorizationHeader2(string method, string now, HttpWebRequest request, string storageAccount,
        string storageKey, string containerName, string blobName)
    {

        string headerResource = $"x-ms-blob-type:BlockBlob\nx-ms-date:" + now + "\nx-ms-version:2017-04-17";
        string urlResource = "/xyz/notes/test567";
        string stringToSign = method + "\n\n\n" + request.ContentLength +
            "\n\n" + request.ContentType + "\n\n\n\n\n\n\n" + headerResource + "\n" + urlResource;


        HMACSHA256 hmac = new HMACSHA256(Convert.FromBase64String(storageKey));
        string signature = Convert.ToBase64String(hmac.ComputeHash(Encoding.UTF8.GetBytes(stringToSign)));

        String AuthorizationHeader = String.Format("{0} {1}:{2}", "SharedKey", storageAccount, signature);
        return AuthorizationHeader;
    }
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

来自 C# 的 Azure BLOB 存储 REST 调用 的相关文章

  • ASP.NET MVC 中的经典 ASP (C#)

    我有一个应用程序想要 最终 转换为 ASP NET MVC 我想要进行全面的服务升级 到 ASP NET 但想要使用当前的 ASP 内容来运行当前的功能 这样我就可以在对新框架进行增量升级的同时升级小部分 该站点严重依赖于不太成熟的 VB6
  • OpenCv读/写视频色差

    我试图简单地使用 openCV 打开视频 处理帧并将处理后的帧写入新的视频文件 我的问题是 即使我根本不处理帧 只是打开视频 使用 VideoCapture 读取帧并使用 VideoWriter 将它们写入新文件 输出文件看起来比输入更 绿
  • 在搜索 List 时,为什么 Enumerable.Any(Func predicate) 比带有 if 语句的 foreach 慢

    最近有件事引起了我的好奇心 Why is the Enumerable Any Func
  • 向 ExpandoObject 添加方法时,“关键字 'this' 在静态属性、静态方法或静态字段初始值设定项中无效”

    我尝试向 ExpandoObject 添加一个动态方法 该方法将返回属性 动态添加 给它 但它总是给我错误 我在这里做错了什么吗 using System using System Collections Generic using Sys
  • 使用post方法将多个参数发送到asp.net core 3 mvc操作

    使用 http post 方法向 asp net mvc core 3 操作发送具有多个参数的 ajax 请求时存在问题 参数不绑定 在 dot net 框架 asp net web api 中存在类似的限制 但在 asp net mvc
  • 从 MVC 迁移到 ASP.NET Core 3.1 中的端点路由时,具有角色的 AuthorizeAttribute 不起作用

    我正在尝试将我的项目从 UseMVC asp net core 2 2 兼容样式 升级到 UseEndpoint Routing 并且我的所有请求都被重定向到我的验证失败页面 它与声明有关 如果我删除 Authorize Roles Adm
  • 构造函数中显式关键字的使用

    我试图了解 C 中显式关键字的用法 并查看了这个问题C 中的explicit关键字是什么意思 https stackoverflow com questions 121162 但是 那里列出的示例 实际上是前两个答案 对于用法并不是很清楚
  • POCO HTTPSClientSession 发送请求时遇到问题 - 证书验证失败

    我正在尝试使用 POCO 库编写一个向服务器发出 HTTPS 请求的程序 出于测试目的 我正在连接到具有自签名证书的服务器 并且我希望允许客户端进行连接 为了允许这种情况发生 我尝试安装InvalidCertificateHandler这是
  • C++ 异步线程同时运行

    我是 C 11 中线程的新手 我有两个线程 我想让它们同时启动 我可以想到两种方法 如下 然而 似乎它们都没有按照我的预期工作 他们在启动另一个线程之前启动一个线程 任何提示将不胜感激 另一个问题是我正在研究线程队列 所以我会有两个消费者和
  • ASP MVC:服务应该返回 IQueryable 的吗?

    你怎么认为 你的 DAO 应该返回一个 IQueryable 以便在你的控制器中使用它吗 不 您的控制器根本不应该处理任何复杂的逻辑 保持苗条身材 模型 而不是 DAO 应该将控制器返回给视图所需的所有内容 我认为在控制器类中看到查询 甚至
  • 如何识别 WPF 文本框中的 ValidationError 工具提示位置

    我添加了一个箭头来指示工具提示中的文本框 当文本框远离屏幕边缘时 这非常有效 但是当它靠近屏幕边缘时 工具提示位置发生变化 箭头显示在左侧 Here is the Image Correct as expected since TextBo
  • Qt 创建布局并动态添加小部件到布局

    我正在尝试在 MainWindow 类中动态创建布局 我有四个框架 它们是用网格布局对象放置的 每个框架都包含一个自定义的 ClockWidget 我希望 ClockWidget 对象在调整主窗口大小时相应地调整大小 因此我需要将它们添加到
  • 基于xsd模式生成xml(使用.NET)

    我想根据我的 xsd 架构 cap xsd 生成 xml 文件 我找到了这篇文章并按照说明进行操作 使用 XSD 文件生成 XML 文件 https stackoverflow com questions 6530424 generatin
  • 将构建日期放入“关于”框中

    我有一个带有 关于 框的 C WinForms 应用程序 我使用以下方法将版本号放入 关于 框中 FileVersionInfo GetVersionInfo Assembly GetExecutingAssembly Location F
  • 获取 2 个数据集 c# 中的差异

    我正在编写一个简短的算法 它必须比较两个数据集 以便可以进一步处理两者之间的差异 我尝试通过合并这两个数据集并将结果更改放入新的数据集来实现此目标 我的方法如下所示 private DataSet ComputateDiff DataSet
  • 如何一步步遍历目录树?

    我发现了很多关于遍历目录树的示例 但我需要一些不同的东西 我需要一个带有某种方法的类 每次调用都会从目录返回一个文件 并逐渐遍历目录树 请问我该怎么做 我正在使用函数 FindFirstFile FindNextFile 和 FindClo
  • 尚未处理时调用 Form 的 Invoke 时出现 ObjectDisposeException

    我们得到一个ObjectDisposedException从一个电话到Invoke在尚未处理的表格上 这是一些演示该问题的示例代码 public partial class Form2 Form void Form2 Load object
  • 什么是 __declspec 以及何时需要使用它?

    我见过这样的例子 declspec在我正在阅读的代码中 它是什么 我什么时候需要使用这个构造 这是 Microsoft 对 C 语言的特定扩展 它允许您使用存储类信息来赋予类型或函数属性 文档 declspec C https learn
  • WinRT 定时注销

    我正在开发一个 WinRT 应用程序 要求之一是应用程序应具有 定时注销 功能 这意味着在任何屏幕上 如果应用程序空闲了 10 分钟 应用程序应该注销并导航回主屏幕 显然 执行此操作的强力方法是在每个页面的每个网格上连接指针按下事件 并在触
  • 使用 CSharpCodeProvider 类编译 C# 7.3 的 C# 编译器版本是什么?

    我想使用 Microsoft CSharp CSharpCodeProvider 类来编译 C 7 3 代码 编译器版本在 IDictionary 中指定 在创建新的 CSharpCodeProvider 时将其作为输入 例如 Compil

随机推荐

  • 将十六进制转换为 RGBA

    我的小提琴 http jsbin com pitu 1 edit 我想尝试一个简单的十六进制到 RGBA 的转换 我使用过的浏览器默认使用 rgb 渲染颜色 因此当使用 farbtastic 颜色选择器时 我通过抓取十六进制值生成的背景颜色
  • 使用 RegEx(notepad++) 删除重复的字符串/单词(不是行)

    我想知道一种使用 notepad 正则表达式查找工具删除文本文件 而不是行 中重复单词或字符串的方法 我只看到了使用 TextFx 删除重复行的方法 但这不是我想要的 例子 123 789 123 321 删除 123 将导致 123 78
  • 如何在webrtc中的canvas流上添加音频流

    我想将通过 getusermedia 获得的音频流添加到画布流并将其发送到远程对等点 于是我抬头一看 有addTrack 但addTrack 似乎不能正常工作 我在 chrome 上运行 var audioTracks navigator
  • 每像素碰撞 - 代码解释

    我目前正在尝试了解每像素碰撞检测 这是我不明白的代码 static bool IntersectPixels Rectangle rectangleA Color dataA Rectangle rectangleB Color dataB
  • Microsoft Office Excel 无法访问文件“c:\inetpub\wwwroot\Timesheet\App_Data\Template.xlsx”

    我的代码如下 Microsoft Office Interop Excel Application oXL null Microsoft Office Interop Excel Sheets sheets Application exce
  • 奇数按降序排列,偶数按升序排列

    给定一个随机整数数组 将奇数元素按降序排序 偶数元素按升序排序 输入示例 1 4 5 2 3 6 7 Output 7 5 3 1 2 4 6 针对时间复杂度进行优化 它是哪种语言 C 或 C 我看到两个标签 在 C 中 您可以使用std
  • 这是 async-await 如何工作的正确图表吗?

    我将尝试就以下问题发表演讲async await我正在创建一个流程图 试图显示可能的执行顺序 我试图根据这些段落来确定这一点 异步方法的开头就像任何其他方法一样执行 方法 也就是说 它同步运行 直到遇到 等待 或 抛出异常 await 关键
  • 为什么我在 JavaScript 中点击按钮后该值显示然后又消失?

    每当我单击按钮时 我都会在文本字段 结果 中得到一秒钟的输出 然后它就消失了 为什么它消失了 我试图将该功能放在身体中 它没有帮助
  • 对 pthread 互斥体涉及的完整内存屏障的澄清

    我听说在处理互斥锁时 必要的内存屏障是由 pthread API 本身处理的 我想了解有关此事的更多细节 这些说法是真的吗 至少在最常见的架构上是这样吗 编译器是否能够识别这种隐式屏障 并在生成代码时避免对操作 从本地寄存器读取进行重新排序
  • mysqldump 没有数据库名称

    是否可以以 xml 格式转储数据 而输出中不包含数据库名称 如果我使用 xml 选项转储这样的输出 gt mysqldump xml my database name my table gt my table xml 然后我的输出是这样的
  • 如何使用 UDID 或设备令牌进行安全登录?

    所以我正在制作一个应用程序 我希望用户能够添加 编辑和评价内容 但我不想强迫他们注册 相反 我计划仅使用他们的设备 ID 或设备令牌来识别他们 我计划同时制作 iPhone 和 Android 版本 因此我正在寻找通用解决方案 但 iPho
  • JSF - 即使退出应用程序后,我的 backbean 的字段也没有被清理

    我是 JSF 的初学者 遇到以下问题 我有一个带有 backbean 的视图 我填充了一些值来执行搜索并显示结果 当我出去并返回应用程序时 最新请求的值仍保留在那里 我在我的 bean 中使用以下注释 Component requestBe
  • Java 8 LocalDateTime 正在解析无效的日期时间

    我想在客户端验证日期时间 所以我编写了以下代码 但我没有得到异常 而是得到了 2 月 31 日日期字符串的正确日期时间对象 这显然是一个无效日期 public class Test public static void main Strin
  • Azure Database for MySQL - webapp Nodejs

    所以我一直在使用本地 mysql 工作台开发一个网络应用程序 我最近将数据库移至 Azure Database for MySQL 在我离开当地之前 一切都运转正常 我的所有网页都工作正常 现在 4 个页面中只有 2 个可以工作 当我单击损
  • Google 地图 API - 获取我的自定义地图 [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 目前不接受答案 我在 Google API 中搜索下载地图的方法 google com mymaps 我所说的下载地图是指 POI 除了 Google 地图引擎 a
  • 如何将加号与字符类一起使用作为正则表达式的一部分?

    在 cygwin 中 这不会返回匹配项 echo aaab grep ab 但这确实返回一个匹配项 echo aaab grep ab ab aaab 这两个表达方式不一样吗 有没有办法表达 字符类的一个或多个字符 而无需输入字符类两次 如
  • 需要显式转换以指向 void 指针[重复]

    这个问题在这里已经有答案了 我有以下函数签名 int foo void 我试图给它一个指向char指针 即char 我的编译器抱怨以下警告 argument of type char is incompatible with paramet
  • 由于缺少 libmysql,在 Windows 上安装 mysql-2.9.0 gem 失败

    我正在尝试在 Windows Server 2003 上安装 Redmine 2 1 4 为了让它工作 我需要安装activerecord mysql adaptergem 而这又似乎依赖于mysql 2 9 0 gem 我从下载了后者ru
  • 在 CherryPy 中使用映射

    In the 调度 其他调度员 CherryPy 文档部分 有一个 Django 风格的正则表达式到视图函数映射定义的示例 但没有说明如何将其附加到cherrypy tree 你应该如何注册这个映射 Edit 基于 正则表达式 URL 映射
  • 来自 C# 的 Azure BLOB 存储 REST 调用

    我正在尝试通过控制台应用程序与 Azure Blob 存储上的容器进行通信 我无法使用 SDK 因此 REST 是我唯一的选择 语言是 C 带有 NET 4 5 2 我已经尝试过这两个代码并且都返回相同的错误 Azure Rest API