• .NET CORE 对接天翼云 OOS


    最近,因公司项目需要对接天翼云OOS,在百度多次折腾后,大部分的都是基于java、php 等其他语言,很少基于C#语言的相关资料,即使有也是基于.NET Framwork开发的SDK,内容几乎是千篇一律,很少基于.NET CORE的开发。在官网上也很少发现基于C#语言的身影,最终在网上找寻到OOS相关的SDK集合中找到基于.NET(C#) SDK开发包

    根据SDK开发包指引迫不及待的在.NET CORE 项目中尝试,但最终还是以失败告终。然后再.NET Framework 环境中居然能成功,百思不得其解,于是联系联系电信售后那边,最终从电信技术人员口中得知,不支持.NET CORE。

    最终,参考OOS开发者文档,采用调用http接口的方式实现,恼火的部分,不是接口的调用,而是签名算法,这个折腾了好几天,最终采用将文档中的java代码翻译成C#代码搞定。第一次写博客,那直接就上代码,通过下面的封装既可以在.NET Framework中使用,也可以在.NET core中使用,

    第一步:实现签名算法:

        /// <summary>
        /// 天翼云OOS签名V2版本
        /// </summary>
        public class CtyunOOSSignatureV2
        {
            /// <summary>
            /// 账号
            /// </summary>
            private String secretkey;
    
            /// <summary>
            /// 秘钥
            /// </summary>
            private string accessKey;
    
            /// <summary>
            /// 
            /// </summary>
            /// <param name="secretkey">秘钥</param>
            /// <param name="accessKey">账号</param>
            /// <param name="region"></param>
            public CtyunOOSSignatureV2(string accessKey,String secretkey)
            {
                this.secretkey = secretkey;
                this.accessKey = accessKey;
            }
    
            /// <summary>
    
            /// HMACSHA1算法加密并返回ToBase64String
    
            /// </summary>
    
            /// <param name="strText">签名参数字符串</param>
    
            /// <param name="strKey">密钥参数</param>
    
            /// <returns>返回一个签名值(即哈希值)</returns>
    
            private string ToBase64hmac(string strKey, string strText)
    
            {
    
                HMACSHA1 myHMACSHA1 = new HMACSHA1(Encoding.UTF8.GetBytes(strKey));
    
                byte[] byteText = myHMACSHA1.ComputeHash(Encoding.UTF8.GetBytes(strText));
    
                return System.Convert.ToBase64String(byteText);
    
            }
    
    
            private string GetStringToSign(string httpVerb, String contentType, string date, string uri)
            {
                String stringToSign = httpVerb + "
    
    "+ contentType + "
    " + date + "
    " + uri;
    
    
                return stringToSign;
            }
            
            /// <summary>
            /// 获取认证签名信息
            /// </summary>
            /// <param name="httpVerb">请求方法</param>
            /// <param name="date">请求时间</param>
            /// <param name="uri">存储桶</param>
            /// <param name="objectname">存储对象名称</param>
            /// <returns></returns>
            public string AuthorizationSignature(string httpVerb,String contentType, string date, string uri)
            {
    
                var stringToSign = GetStringToSign(httpVerb, contentType,date, uri);
    
                var signature = ToBase64hmac(this.secretkey, stringToSign);
    
                return "AWS " + this.accessKey + ":" + signature;
    
            }
        }

    第二步:实现接口调用:

     public interface IOOSHelper
        {
            /// <summary>
            /// 设置配置信息
            /// </summary>
            /// <param name="serviceURL">云地址</param>
            /// <param name="accessKey">oos账号</param>
            /// <param name="secretKey">oos密码</param>
            /// <param name="bucketName">存储桶</param>
            void InitOOSHelper(string serviceURL, string accessKey, string secretKey, string bucketName);
    
    
            /// <summary>
            /// 上传文件
            /// </summary>
            /// <param name="stream">文件流</param>
            /// <param name="objectname">商户号+文件名称,例如:99999/1.JPG</param>
            /// <param name="msg">如果成功返回文件存储地址;失败返回错误原因</param>
            /// <returns></returns>
            Boolean UploadFile(Stream inputStream, string objectname,ref string msg);
        }
    

      

        public class CtyunOOSHttpHelper : IOOSHelper
        {
            private readonly String root_dir = "WeChatApp";
            /// <summary>
            /// 天翼云oos账号
            /// </summary>
            private string _accessKey;
    
            /// <summary>
            /// 天翼云oos密码
            /// </summary>
            private string _secretKey;
    
            /// <summary>
            /// 存储桶
            /// </summary>
            private string _bucketName;
    
            /// <summary>
            /// 天翼云地址
            /// </summary>
            private string _serviceURL;
    
            private CtyunOOSSignatureV2 signature;
    
            public void InitOOSHelper(string serviceURL, string accessKey, string secretKey, string bucketName)
            {
                this._serviceURL = serviceURL;
                this._accessKey = accessKey;
                this._secretKey = secretKey;
                this._bucketName = bucketName;
    
                signature = new CtyunOOSSignatureV2(accessKey, secretKey);
    
            }
    
            /// <summary>
            /// 上传文件
            /// </summary>
            /// <param name="stream">文件流</param>
            /// <param name="objectname">商户号+文件名称,例如:99999/1.JPG</param>
            /// <param name="msg">如果成功返回文件存储地址;失败返回错误原因</param>
            /// <returns></returns>
            public bool UploadFile(Stream stream, string objectname,ref String msg)
            {
                Boolean success = true;
               
                int filelength = 0;
    
                filelength = (int)stream.Length; //获得文件长度 
    
                byte[] data = new Byte[filelength]; //建立一个字节数组 
    
                stream.Read(data, 0, filelength); //按字节流读取 
    
                HttpRequestHelper httpReqHelper = new HttpRequestHelper(this._serviceURL);
    
                string uri = this._bucketName + "/" + root_dir+ "/" + objectname;
    
                String datetime = DateTime.Now.ToUniversalTime().ToString("R"); 
    
                var authorization = signature.AuthorizationSignature(HttpRequestHelper.HttpType.PUT.ToString(), "image/jpeg", datetime, "/" + uri);
    
                Dictionary<String, string> headers = new Dictionary<string, string>();
    
                headers.Add("Date", datetime);
                headers.Add("Content-Type", "image/jpeg");
                headers.Add("Authorization", authorization);
                try
                {
                    httpReqHelper.AddRequestHeaders(headers);
                   msg= httpReqHelper.HttpRequest(uri, HttpRequestHelper.HttpType.PUT, data);
    
                    if (String.IsNullOrEmpty(msg))
                        msg = this._serviceURL +"/"+ uri;
    
                }
                catch (Exception ex)
                {
                    msg= ex.Message;
                    success = false;
                }
                return success;
            }
        }
    

     

    第三步:编写单元测试

     [TestClass]
        public class UnitOOSTest
        {
    
            private static String accessKey = "b7f***********bb13c4f6";
            private static String secretKey = "9e1739f4986ba***********a4f85b20bdcf";
            // API 服务器
            private static String OOS_SERVICE = "http://oos-***.ctyunapi.cn";
            private static String bucketName = "dx-****-dev";
    
            [TestMethod]
            public void TestOOSUploadFile()
            {
    
                IOOSHelper ctyunOOSHelper = new CtyunOOSHttpHelper();
             
                ctyunOOSHelper.InitOOSHelper(OOS_SERVICE, accessKey, secretKey, bucketName);
    
                string msg=string.Empty;
    
                using (var fs = new FileStream(@"f:181256.jpg", FileMode.Open))
                {
    
                    ctyunOOSHelper.UploadFile(fs, "1121212/181256.jpg", ref msg);
                }
    
                Console.ReadKey();
            }
        }
    

      以上即是调用OOS的全部代码。

    以上项目中用到httphelper帮助类:

        public class HttpRequestHelper
        {
            private static string BaseUri;
    
            /// <summary>
            /// 
            /// </summary>
            private Dictionary<String, string> headers;
    
            public HttpRequestHelper(string baseUri)
            {
                BaseUri = baseUri;
            }
    
    
            #region Delete方式
            private   string Delete(string uri, byte[] data)
            {
                string serviceUrl = "";
                if (BaseUri == "" || BaseUri == null)
                {
                    serviceUrl = uri;
                }
                else
                {
                    serviceUrl = string.Format("{0}/{1}", BaseUri, uri);
                }
                return CommonHttpRequest(serviceUrl, "DELETE", data);
            }
            #endregion
            #region Put方式
            private   string Put(string uri, byte[] data)
            {
                string serviceUrl = "";
                if (BaseUri == "" || BaseUri == null)
                {
                    serviceUrl = uri;
                }
                else
                {
                    serviceUrl = string.Format("{0}/{1}", BaseUri, uri);
                }
                return CommonHttpRequest(serviceUrl, "PUT", data);
            }
            #endregion
            #region POST方式实现
    
    
            private   string Post(string uri, byte[] data)
            {
                string serviceUrl = "";
                if (BaseUri == "" || BaseUri == null)
                {
                    serviceUrl = uri;
                }
                else
                {
                    serviceUrl = string.Format("{0}/{1}", BaseUri, uri);
                }
                return CommonHttpRequest(serviceUrl, "Post", data);
            }
            #endregion
            #region GET方式实现
            private   string Get(string uri)
            {
                string serviceUrl = "";
                if (BaseUri == "" || BaseUri == null)
                {
                    serviceUrl = uri;
                }
                else
                {
                    serviceUrl = string.Format("{0}/{1}", BaseUri, uri);
                }
                return CommonHttpRequest(serviceUrl, "GET", null);
            }
    
            #endregion
            #region  私有方法
            private  string CommonHttpRequest(string url, string reqType, byte[] data)
            {
                HttpWebRequest webRequest = null;
                Stream outstream = null;
                HttpWebResponse myResponse = null;
                StreamReader reader = null;
                try
                {
                    //构造http请求的对象
                    webRequest = (HttpWebRequest)WebRequest.Create(url);
    
    
                    //设置
                    webRequest.ProtocolVersion = HttpVersion.Version11;
                    webRequest.Method = reqType;
    
                    if(headers !=null && headers.Count>0)
                    {
                        foreach(var header in headers)
                        webRequest.Headers.Add(header.Key,header.Value);
                    }
                    
                    if (data !=null&&data.Length >0)
                    {
                        webRequest.ContentLength = data.Length;
                       
                        //转成网络流
                        byte[] buf = data;
    
                        outstream = webRequest.GetRequestStream();
                        outstream.Flush();
                        outstream.Write(buf, 0, buf.Length);
                        outstream.Flush();
                        outstream.Close();
                    }
                    // 获得接口返回值
                    myResponse = (HttpWebResponse)webRequest.GetResponse();
                    reader = new StreamReader(myResponse.GetResponseStream(), Encoding.UTF8);
                    string ReturnXml = reader.ReadToEnd();
                    reader.Close();
                    myResponse.Close();
                    webRequest.Abort();
                    return ReturnXml;
                }
                catch (Exception ex)
                {
                    if (outstream != null) outstream.Close();
                    if (reader != null) reader.Close();
                    if (myResponse != null) myResponse.Close();
                    if (webRequest != null) webRequest.Abort();
                    throw ex;
                }
            }
    
            #endregion
    
    
            #region 通用请求
            /// <summary>
            /// Http通用请求
            /// </summary>
            /// <param name="url"></param>
            /// <param name="type"></param>
            /// <param name="data"></param>
            /// <returns></returns>
            public string HttpRequest(string url, HttpType type, byte[] data)
            {
                switch (type)
                {
                    case HttpType.PUT:
                        return Put(url, data);
                    case HttpType.GET:
                        return Get(url);
                    case HttpType.POST:
                        return Post(url, data);
                    case HttpType.DELETE:
                        return Delete(url, data);
                    default:
                        break;
                }
                return "";
            }
    
            /// <summary>
            /// 添加请求头
            /// </summary>
            /// <param name="headers"></param>
            public void AddRequestHeaders(Dictionary<String,string> headers)
            {
                this.headers = headers;
            }
    
            /// <summary>
            /// Http通用请求
            /// </summary>
            /// <param name="ip"></param>
            /// <param name="port"></param>
            /// <param name="uri"></param>
            /// <param name="type"></param>
            /// <param name="data"></param>
            /// <returns></returns>
            public string HttpRequest(string ip, string port, string uri, HttpType type, byte[] data)
            {
                string url = "http://" + ip + ":" + port + uri;
                return HttpRequest(url, type, data);
            }
    
    
            #endregion
    
    
            public enum HttpType
            {
                PUT = 0,
                GET = 1,
                POST = 2,
                DELETE = 3
    
    
            }
        }
    

     注意事项:

    1、根据本人与天翼云技术沟通,目前他们注意是支持的oos开发者文档中的v2签名格式,v4测试过几次,并没有通过,如果有实现了的小伙伴可以分享一下,不足之处请多多指教!

    2、注意系统调用的时间应该采用DateTime.Now.ToUniversalTime(),而不是DateTime.Now,如果时间不对也无法上传;

    3、由于是采用的异步上传,其实文件上传后的路径,即为请求地址+文件路径。

    您的资助是我最大的动力!
    金额随意,欢迎来赏!

    如果,您认为阅读这篇博客让您有些收获,不妨点击一下右下角的推荐按钮
    如果,您希望更容易地发现我的新博客,不妨点击一下绿色通道的关注我

    如果,想给予我更多的鼓励,求打

    因为,我的写作热情也离不开您的肯定支持,感谢您的阅读,我是懒惰的程序员

  • 相关阅读:
    Eclipse配置Maven的本地仓库和阿里云镜像 加速Maven更新
    layui弹出层基础参数
    鼠标悬停设置layui tips提示框
    Java实现文本中的关键字高亮,匹配所有长度
    获取指定格式的系统时间
    截取过长的字符,多余的字符将由省略号代替
    身份证处理方法(15转18,出生日期隐藏)
    layDate面板出现红色花纹图案
    layer单选框 radio的问题总结
    Android--多线程之Handler
  • 原文地址:https://www.cnblogs.com/JackXiong/p/10875953.html
Copyright © 2020-2023  润新知