如何使用c#中的共享密钥(Rest Api)将文件上传到azure数据湖存储生成2? [英] How to Upload files to azure data lake storage generation 2 using shared key (Rest Api) in c#?

查看:85
本文介绍了如何使用c#中的共享密钥(Rest Api)将文件上传到azure数据湖存储生成2?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

<跨度风格= "颜色:#333333;字体家庭: '的Segoe UI', '很好的可读性',宋体,Arial字体,黑体,无衬线;字体大小:14px的">欲知道一种使用c#中的共享密钥(Rest API)在天蓝色数据湖存储生成2上传文件的方法。

我在上传文件时遇到问题。它给出了以下错误。

I am facing issue in uploading files. It gives below error.




下面是我的代码.File正在正确创建但是当我尝试在创建的文件中附加数据时它失败。如果我是,请帮助我   做错了。

Below is my code.File is getting created properly But it fails when i try to append data in created file.Please assist me if i am   doing anything wrong.

  &NBSP;

   

私有静态AuthenticationHeaderValue GetAuthorizationHeaderUpload(

&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;串storageAccountName,串storageAccountKey,日期时间现在,

&NBSP;&NBSP;&NBSP;&NBSP;&NBSP; httpRequestMessage httpRequestMessage,串ifMatch = QUOT;" ;,串MD5 = QUOT;")

&NBSP; &NBSP; &NBSP; &NBSP; {

  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; AuthenticationHeaderValue authHV = null;

  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP;试试
  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; {

  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; //这是邮件签名的原始表示。

  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; HttpMethod方法= httpRequestMessage.Method;

  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; String MessageSignature = String.Format(" {0} \\\
\\\
\ n {1} \\\
{5} \ n \ n \ n \\ n {2} \ n \ n \ n \\ n {3} {4} \ n {5} \ n {6}",&b $ b        &NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP; method.ToString(),

&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP; &NBSP;(方法== HttpMethod.Get ||方法== HttpMethod.Head ||方法== HttpMethod.Put ||方法== HttpMethod.Delete)的String.Empty

&NBSP;?&NBSP; &NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;:httpRequestMessage.Content.Headers.ContentLength.ToString(),

&NBSP;&NBSP;&NBSP ;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP; ifMatch,

&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP ;    GetCanonicalizedHeaders(httpRequestMessage),

     & nbsp;        GetCanonicalizedResource(httpRequestMessage.RequestUri,storageAccountName),

  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; md5);
$


  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; //现在把它变成一个字节数组。

  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; byte [] SignatureBytes = Encoding.UTF8.GetBytes(MessageSignature);



  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; //创建存储密钥的HMACSHA256版本。

  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; HMACSHA256 SHA256 =新HMACSHA256(Convert.FromBase64String(storageAccountKey));



  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; //计算SignatureBytes的哈希值并将其转换为base64字符串。

  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; string signature = Convert.ToBase64String(SHA256.ComputeHash(SignatureBytes));



  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; //这是将添加到请求标头列表的实际标头。

  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; //你可以在这里停止代码并在返回之前查看'authHV'的值。

  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; authHV =新AuthenticationHeaderValue(QUOT; SharedKey" ;,

&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP; storageAccountName + QUOT;:" + Convert.ToBase64String( SHA256.ComputeHash(SignatureBytes)));

  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; }¥b $ b  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; catch(例外情况)

  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; {

  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; authHV = null;

  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; }¥b $ b  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP;返回authHV;

  &NBSP; &NBSP; &NBSP; }

private static AuthenticationHeaderValue GetAuthorizationHeaderUpload(
         string storageAccountName, string storageAccountKey, DateTime now,
         HttpRequestMessage httpRequestMessage, string ifMatch = "", string md5 = "")
        {
            AuthenticationHeaderValue authHV = null;
            try
            {
                // This is the raw representation of the message signature.
                HttpMethod method = httpRequestMessage.Method;
                String MessageSignature = String.Format("{0}\n\n\n{1}\n{5}\n\n\n\n{2}\n\n\n\n{3}{4}\n{5}\n{6}",
                          method.ToString(),
                          (method == HttpMethod.Get || method == HttpMethod.Head || method == HttpMethod.Put || method == HttpMethod.Delete) ? String.Empty
                            : httpRequestMessage.Content.Headers.ContentLength.ToString(),
                          ifMatch,
                          GetCanonicalizedHeaders(httpRequestMessage),
                          GetCanonicalizedResource(httpRequestMessage.RequestUri, storageAccountName),
                          md5);

                // Now turn it into a byte array.
                byte[] SignatureBytes = Encoding.UTF8.GetBytes(MessageSignature);

                // Create the HMACSHA256 version of the storage key.
                HMACSHA256 SHA256 = new HMACSHA256(Convert.FromBase64String(storageAccountKey));

                // Compute the hash of the SignatureBytes and convert it to a base64 string.
                string signature = Convert.ToBase64String(SHA256.ComputeHash(SignatureBytes));

                // This is the actual header that will be added to the list of request headers.
                // You can stop the code here and look at the value of 'authHV' before it is returned.
                authHV = new AuthenticationHeaderValue("SharedKey",
                   storageAccountName + ":" + Convert.ToBase64String(SHA256.ComputeHash(SignatureBytes)));
            }
            catch (Exception ex)
            {
                authHV = null;
            }
            return authHV;
        }

  ///< summary>

  &NBSP; &NBSP; &NBSP; ///将以x-ms开头的标题放在列表中并对其进行排序。

  &NBSP; &NBSP; &NBSP; ///然后将它们格式化为一串[key:value\]值连接成一个字符串。

  &NBSP; &NBSP; &NBSP; ///(Canonicalized Headers =格式标准化的标题)。

  &NBSP; &NBSP; &NBSP; ///< / summary>

  &NBSP; &NBSP; &NBSP; ///< param name =" httpRequestMessage">将对存储服务发出的请求。< / param>

  &NBSP; &NBSP; &NBSP; ///< returns>错误消息;如果没问题,请留空。< / returns>

  &NBSP; &NBSP; &NBSP;私有静态字符串GetCanonicalizedHeaders(HttpRequestMessage httpRequestMessage)

  &NBSP; &NBSP; &NBSP; {

  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; var headers =来自httpRequestMessage.Headers中的kvp

  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP;其中kvp.Key.StartsWith(" x-ms-",StringComparison.OrdinalIgnoreCase)

  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; orderby kvp.Key

  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP;选择新的{Key = kvp.Key.ToLowerInvariant(),kvp.Value};
$


  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; StringBuilder sb = new StringBuilder();



  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; //以正确的格式创建字符串;这就是使标题"标准化"的原因。 -

  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; //&NBSP;  表示标准格式。 http://en.wikipedia.org/wiki/Canonicalization

  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; foreach(标题中的var kvp)

  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; {

  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; StringBuilder headerBuilder = new StringBuilder(kvp.Key);

  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; char separator =':';
$


  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; //获取每个标题的值,如果找到则删除\\ n,然后用密钥附加它。

  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; foreach(字符串headerValues in kvp.Value)

  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; {

  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; string trimmedValue = headerValues.TrimStart()。替换(" \\\\ n",String.Empty);

  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; headerBuilder.Append(separator).Append(trimmedValue);



  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; //将其设置为逗号;这只会被使用 

  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; //&NBSP;  如果其中一个标题有多个值。

  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; separator =',';

  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; }¥b $ b  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; sb.Append(headerBuilder.ToString())。追加(" \ n");

  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; }¥b $ b  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; return sb.ToString();

  &NBSP; &NBSP; &NBSP; }

  /// <summary>
        /// Put the headers that start with x-ms in a list and sort them.
        /// Then format them into a string of [key:value\n] values concatenated into one string.
        /// (Canonicalized Headers = headers where the format is standardized).
        /// </summary>
        /// <param name="httpRequestMessage">The request that will be made to the storage service.</param>
        /// <returns>Error message; blank if okay.</returns>
        private static string GetCanonicalizedHeaders(HttpRequestMessage httpRequestMessage)
        {
            var headers = from kvp in httpRequestMessage.Headers
                          where kvp.Key.StartsWith("x-ms-", StringComparison.OrdinalIgnoreCase)
                          orderby kvp.Key
                          select new { Key = kvp.Key.ToLowerInvariant(), kvp.Value };

            StringBuilder sb = new StringBuilder();

            // Create the string in the right format; this is what makes the headers "canonicalized" --
            //   it means put in a standard format. http://en.wikipedia.org/wiki/Canonicalization
            foreach (var kvp in headers)
            {
                StringBuilder headerBuilder = new StringBuilder(kvp.Key);
                char separator = ':';

                // Get the value for each header, strip out \r\n if found, then append it with the key.
                foreach (string headerValues in kvp.Value)
                {
                    string trimmedValue = headerValues.TrimStart().Replace("\r\n", String.Empty);
                    headerBuilder.Append(separator).Append(trimmedValue);

                    // Set this to a comma; this will only be used 
                    //   if there are multiple values for one of the headers.
                    separator = ',';
                }
                sb.Append(headerBuilder.ToString()).Append("\n");
            }
            return sb.ToString();
        }

  ///< summary>

  &NBSP; &NBSP; &NBSP; ///签名字符串的这一部分代表存储帐户 

  &NBSP; &NBSP; &NBSP; ///&NBSP;  请求的目标。还将包含任何其他查询参数/值。

  &NBSP; &NBSP; &NBSP; ///对于ListContainers,这将返回如下内容:

  &NBSP; &NBSP; &NBSP; ///&NBSP;   / storageaccountname / \ ncomp:list

  &NBSP; &NBSP; &NBSP; ///< / summary>

  &NBSP; &NBSP; &NBSP; ///< param name =" address">存储服务的URI。< / param>

  &NBSP; &NBSP; &NBSP; ///< param name =" accountName">存储帐户名称。< / param>

  &NBSP; &NBSP; &NBSP; ///< returns>表示规范化资源的字符串。< / returns>

  &NBSP; &NBSP; &NBSP;私有静态字符串GetCanonicalizedResource(Uri地址,字符串storageAccountName)

  &NBSP; &NBSP; &NBSP; {

  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; //绝对路径是"/"因为我们收到了一个集装箱清单。

  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; StringBuilder sb = new StringBuilder(" /")。Append(storageAccountName).Append(address.AbsolutePath);



  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; // Address.Query是资源,例如"?comp = list"。

  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; //这最终得到一个NameValueCollection,其中1个条目有key = comp,value = list。

  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; //如果您有更多查询参数,它会有更多条目。

  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; NameValueCollection values = ParseQueryString(address.Query);



  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; foreach(值中的var项目.AllKeys.OrderBy(k => k))

  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; {

  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; values [item] = WebUtility.UrlDecode(values [item]);

  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; if(!string.IsNullOrEmpty(item))

  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; sb.Append('\ n')。追加(项目)。附加(':')。追加(值[item]);

  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; }


  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; return sb.ToString();



  &NBSP; &NBSP; &NBSP; }

 /// <summary>
        /// This part of the signature string represents the storage account 
        ///   targeted by the request. Will also include any additional query parameters/values.
        /// For ListContainers, this will return something like this:
        ///   /storageaccountname/\ncomp:list
        /// </summary>
        /// <param name="address">The URI of the storage service.</param>
        /// <param name="accountName">The storage account name.</param>
        /// <returns>String representing the canonicalized resource.</returns>
        private static string GetCanonicalizedResource(Uri address, string storageAccountName)
        {
            // The absolute path is "/" because for we're getting a list of containers.
            StringBuilder sb = new StringBuilder("/").Append(storageAccountName).Append(address.AbsolutePath);

            // Address.Query is the resource, such as "?comp=list".
            // This ends up with a NameValueCollection with 1 entry having key=comp, value=list.
            // It will have more entries if you have more query parameters.
            NameValueCollection values = ParseQueryString(address.Query);

            foreach (var item in values.AllKeys.OrderBy(k => k))
            {
                values[item] = WebUtility.UrlDecode(values[item]);
                if (!string.IsNullOrEmpty(item))
                    sb.Append('\n').Append(item).Append(':').Append(values[item]);
            }

            return sb.ToString();

        }




推荐答案

请允许任何人帮助我。


这篇关于如何使用c#中的共享密钥(Rest Api)将文件上传到azure数据湖存储生成2?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆