Как загрузить файлы в RackSpace Cloud Files, используя.net?
Я хочу использовать CDN (облачные файлы) RackSpace для хранения моего статического контента. Проблема в том, что я использую ASP.NET MVC3
и я не видел ни одного текущего рабочего примера того, как это сделать.
Я видел несколько примеров в Интернете, но все они были версии, которую RackSpace больше не поддерживает. Вы можете подтвердить это здесь на их Примечание:
http://www.rackspace.com/knowledge_center/article/sample-csharp-application-for-cloud-files
И когда вы проверяете учетную запись RackSpace на gitHub под openstack.net, на который перенаправляет их поддержка, вы видите, что поддержка загрузки файлов в Cloud Files отсутствует. Вы можете увидеть это в таблице файлов:
https://github.com/rackspace/openstack.net/wiki/Feature-Support
Как программно загрузить файлы в облачные файлы RackSpace с использованием C#?
2 ответа
Вы правы, на данный момент проект openstack.net не поддерживает CloudFiles. Эта функциональность планируется выпустить в конце этого месяца (середина апреля). Вы по-прежнему можете использовать 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, и синхронный метод, поэтому вам не нужны оба, просто используйте тот, который лучше всего подходит для вас.
Вы также можете использовать библиотеку HttpClient, если у вас установлен пакет Http Client NuGet ( http://nuget.org/packages/Microsoft.Net.Http/2.0.20710.0). Вот образец:
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);
}
Надеюсь, это поможет!
Начиная с 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);
}
Usings:
using net.openstack.Core.Domain;
using net.openstack.Providers.Rackspace;
Просто учтите, что некоторые части являются моими техническими требованиями, такими как генерация слагов, использование Guid, Region и т.д.