【问题标题】:How to upload files to RackSpace Cloud Files using .net?如何使用 .net 将文件上传到 RackSpace Cloud Files?
【发布时间】:2013-03-29 21:01:29
【问题描述】:

我想使用 RackSpace 的 CDN(云文件)来存储我的静态内容。问题是我正在使用ASP.NET MVC3,我还没有看到任何当前的工作示例来说明如何做到这一点。

我在网上看到了几个示例,但它们都是 RackSpace 不再支持的版本。您可以在他们的 Note 上确认:

http://www.rackspace.com/knowledge_center/article/sample-csharp-application-for-cloud-files

当您在 openstack.net 下查看 RackSpace 的 gitHub 帐户(他们的支持重定向到的项目)时,您会看到不支持将文件上传到 Cloud Files。您可以在 Files 表下看到:

https://github.com/rackspace/openstack.net/wiki/Feature-Support

如何使用 C# 以编程方式将文件上传到 RackSpace 的 Cloud Files?

【问题讨论】:

    标签: asp.net-mvc-3 c#-4.0 .net-4.0 rackspace-cloud rackspace


    【解决方案1】:

    你是对的,目前 openstack.net 项目不支持 CloudFiles。该功能定于本月晚些时候(4 月中旬)发布。如果您愿意,您仍然可以使用 csharp-cloudfiles (https://github.com/rackerlabs/csharp-cloudfiles),因为它仍然有效,只是处于弃用状态,不会收到任何更新或错误修复。

    但是,这是一个快速而肮脏的控制台应用程序,使用内置的 HttpWebRequest/Response 对象,它应该可以帮助您在 openstack.net v1.1 发布之前开始使用。

    class Program
    {
        const string filePath = @"Path\FileName";
        const string myToken = "myToken";
        const string url = "Url/Container/FileName";
    
        static void Main(string[] args)
        {
            //Do();
            DoAsync();
        }
    
        static void Do()
        {
            using (var fs = File.Open(filePath, FileMode.Open, FileAccess.Read))
            {
                UploadStream(new Uri(url), fs, myToken,
                    (response) => Console.WriteLine("Upload Complete.  Status Code: {0} ({1})", response.StatusCode, response.StatusDescription));
            }
    
            Console.WriteLine("Done!");
            Console.ReadLine();
        }
    
        static void DoAsync()
        {
            IAsyncResult asyncRes;
            using (var fs = File.Open(filePath, FileMode.Open, FileAccess.Read))
            {
                asyncRes = UploadStreamAsync(new Uri(url), fs, myToken,
                    (asyncResult) =>
                    {
                        var request = (HttpWebRequest)asyncResult.AsyncState;
                        var response = (HttpWebResponse)request.EndGetResponse(asyncResult);
                        Console.WriteLine("Upload Complete.  Status Code: {0} ({1})", response.StatusCode, response.StatusDescription);
                    });
            }
    
            asyncRes.AsyncWaitHandle.WaitOne();
    
            Console.WriteLine("Done!");
            Console.ReadLine();
        }
    
        static IAsyncResult UploadStreamAsync(Uri uri, Stream contents, string token, AsyncCallback resultCallback, int chunkSize = 8 * 1024)
        {
            var req = (HttpWebRequest)WebRequest.Create(uri);
            req.Headers.Add("X-Auth-Token", token);
            req.Method = "PUT";
    
            req.AllowWriteStreamBuffering = false;
            if (req.ContentLength == -1L)
                req.SendChunked = true;
    
            using (Stream stream = req.GetRequestStream())
            {
                var buffer = new byte[chunkSize];
                int count;
                while ((count = contents.Read(buffer, 0, chunkSize)) > 0)
                {
                    stream.Write(buffer, 0, count);
                }
            }
    
            return req.BeginGetResponse(resultCallback, req);
        }
    
        static void UploadStream(Uri uri, Stream contents, string token, Action<HttpWebResponse> resultCallback, int chunkSize = 8 * 1024)
        {
            var req = (HttpWebRequest)WebRequest.Create(uri);
            req.Headers.Add("X-Auth-Token", token);
            req.Method = "PUT";
    
            req.AllowWriteStreamBuffering = false;
            if (req.ContentLength == -1L)
                req.SendChunked = true;
    
            using (Stream stream = req.GetRequestStream())
            {
                var buffer = new byte[chunkSize];
                int count;
                while ((count = contents.Read(buffer, 0, chunkSize)) > 0)
                {
                    stream.Write(buffer, 0, count);
                }
            }
    
            using (var resp = req.GetResponse() as HttpWebResponse)
            {
                resultCallback(resp);
            }
        }
    }
    

    在上面的代码中,我提供了 Async 和 Synchronous 方法,因此您不需要两者,只需使用最适合您的方法即可。

    如果您安装了 Http Client NuGet 包 (http://nuget.org/packages/Microsoft.Net.Http/2.0.20710.0),您也可以使用 HttpClient 库。这是一个示例:

    static void UploadFileToRSCloud(string path, string filename)
    {
        HttpClient client = new HttpClient();
        MemoryStream ms = new MemoryStream();
    
        client.DefaultRequestHeaders.TransferEncodingChunked = true;
    
        var filePath = 
        // Copy the data to the Resource Part 
        using (FileStream fileStream = new FileStream(filename, FileMode.Open, FileAccess.Read))
        {
            CopyStream(fileStream, ms);
        }// end:using(fileStream) - Close and dispose fileStream. 
    
        ms.Position = 0;
        StreamContent sc = new StreamContent(ms);
    
        client.DefaultRequestHeaders.Add("X-Auth-Token", "TOKEN HERE");
    
        var result = client.PutAsync( "UrlBase/Container/ChipperJones.jpg", sc);
    
        result.Wait();
    }
    
    private static void CopyStream(Stream source, Stream target)
    {
        const int bufSize = 0x1000;
        byte[] buf = new byte[bufSize];
        int bytesRead = 0;
        while ((bytesRead = source.Read(buf, 0, bufSize)) > 0)
            target.Write(buf, 0, bytesRead);
    }
    

    希望有帮助!

    【讨论】:

    • 谢谢艾伦,已经解决了。你是回复我票的人。谢谢。
    • @alanquillin 我相信此时 v1.1 已经发布并且不再推荐上面的库?是否有更新的示例在某处与 OpenStack.net 一起使用?
    【解决方案2】:

    截至 2014 年并回复 Marc M,应该这样做:

    首先安装openstack.net包

    https://www.nuget.org/packages/openstack.net/

    PM> Install-Package openstack.net
    

    要上传的代码:

    public static string Upload(Stream stream, string fileName)
    {
        CloudFilesProvider cloudFilesProvider = getProvider();
        IEnumerable<string> containerObjectList = 
            cloudFilesProvider.ListObjects(CONTAINER_NAME, region: REGION_DFW)
            .Select(o => o.Name);
        string extension = Path.GetExtension(fileName);
        string name = Path.GetFileNameWithoutExtension(fileName);
    
        stream.Position = 0;
    
        name = name.GenerateSlug(); //my method
        fileName = name + extension;
    
        while (containerObjectList.Contains(fileName))
            fileName = name + Guid.NewGuid().ToString().Split('-')[0] + extension;
    
        cloudFilesProvider
            .CreateObject(CONTAINER_NAME, stream, fileName, region: REGION_DFW);
    
        return Constants.Rackspace.CloudFiles.PUBLIC_CONTAINER + fileName;
    }
    
    private static CloudFilesProvider getProvider()
    {
        CloudIdentity cloudIdentity = 
            new CloudIdentity() { APIKey = API_KEY, Username = USERNAME };
        return new CloudFilesProvider(cloudIdentity);
    }
    

    用途:

    using net.openstack.Core.Domain;
    using net.openstack.Providers.Rackspace;
    

    请注意,有些部分是我的技术要求,例如生成 slug、使用 Guid、Region 等。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-01-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多