Is it possible download data on Windows Azure via FtpWebRequest (ASP.NET/C#)?
I am doing this currently and not sure if my problem is that FtpWebRequest is in general not working as expected, or if I have a different failure..
Has sb. did this before?
If you're talking about Windows Azure Storage, then definitely not. FTP is not supported.
If you're working with Compute roles, you could write something to support this, but it's DIY, a la:
http://blog.maartenballiauw.be/post/2010/03/15/Using-FTP-to-access-Windows-Azure-Blob-Storage.aspx
I could solve my problem doing the ftp-request with FTPLib.
This means: You can copy/load files to azure or to an external source!
:-)
Make this working also with AlexFTPS , you just need to add StartKeepAlive.
try
{
string fileName = Path.GetFileName(this.UrlString);
Uri uri = new Uri(this.UrlString);
string descFilePath = Path.Combine(this.DestDir, fileName);
using (FTPSClient client = new FTPSClient())
{
// Connect to the server, with mandatory SSL/TLS
// encryption during authentication and
// optional encryption on the data channel
// (directory lists, file transfers)
client.Connect(uri.Host,
new NetworkCredential("anonymous",
"name#email.com"),
ESSLSupportMode.ClearText
);
client.StartKeepAlive();
// Download a file
client.GetFile(uri.PathAndQuery, descFilePath);
client.StopKeepAlive();
client.Close();
}
}
catch (Exception ex)
{
throw new Exception("Failed to download", ex);
}
Related
I'm trying out Azure Blob Change Feed feature and it behaves strange to me with Append Blobs: append events are missing in the feed.
My scenario is:
Create storage account, enable change feed feature:
Change feed enabled
Create Append Blob if not exists (1) and appending some input into it (2).
private void WriteBlob(string input)
{
MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(input));
try
{
if (client == null)
{
var credential = new ClientSecretCredential("...", "...");
client = new AppendBlobClient(new Uri("..."), credential);
}
client.CreateIfNotExists(); // (1)
client.AppendBlock(stream); // (2)
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
Fetch Change Feed entries in separate console app.
public static List<BlobChangeFeedEvent> GetChanges()
{
var credential = new ClientSecretCredential("...", "...");
BlobChangeFeedClient blobChangeFeedClient = new BlobChangeFeedClient(new Uri("..."), credential);
List<BlobChangeFeedEvent> events = new List<BlobChangeFeedEvent>();
foreach (BlobChangeFeedEvent changeFeedEvent in blobChangeFeedClient.GetChanges())
{
events.Add(changeFeedEvent);
}
return events;
}
The problem is that after a few runs of WriteBlob method I only get single change feed event that corresponds to the blob creation, and subsequent appends are missing in the feed, however inputs are being appended successfully to the blob resource.
The question is why it is working this way? I didn't find anything special about Append Blob blob type regarding Change feed in docs.
Currently, the append event for an append blob is not supported.
As per this doc, only the following event types are supported:
BlobCreated
BlobDeleted
BlobPropertiesUpdated
BlobSnapshotCreated
And in the source code of Azure.Storage.Blobs.ChangeFeed package, there is no append event type.
A feature request of this is submitted, hope it can be added in the future release.
Trying to upload a file to Google Cloud Storage using Google APIs Client Library for .Net. Here is my code. It runs fine without any errors but doesn't do the job either. Please advice what I'm missing here, or is it the right way to approach this problem. Apreciate it!
try
{
Google.Apis.Services.BaseClientService.Initializer init = new Google.Apis.Services.BaseClientService.Initializer();
init.ApiKey = "server-apps-API-KEY-HERE";
init.ApplicationName = "Project Default Service Account";
Google.Apis.Storage.v1.StorageService ss = new Google.Apis.Storage.v1.StorageService(init);
Google.Apis.Storage.v1.Data.Object fileobj = new Google.Apis.Storage.v1.Data.Object();
fileobj.ContentType = "image/jpeg";
///READ FILE
string file = #"C:\Photos\TEST.jpg";
System.IO.Stream j = new System.IO.FileStream(file,
System.IO.FileMode.Open,
System.IO.FileAccess.Read);
//New File Name
fileobj.Name = "TEST.jpg";
Google.Apis.Storage.v1.ObjectsResource.InsertMediaUpload insmedia;
insmedia = new Google.Apis.Storage.v1.ObjectsResource.InsertMediaUpload(ss, fileobj, "test-common", j, "image/jpeg");
insmedia.Upload();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
Console.ReadLine();
}
You have not authorized access to your Google Cloud Storage anywhere in your code. See my answer here: Uploading objects to google cloud storage in c# to get example how to do it.
I need to know a way to connect to a FTP site and i am unable to find an example to do the program using C#.
I need to write the code where i could connect, and download files from the FTP server without using third party component.
How can i do this ? Help.
There is FtpWebRequest class in .Net 4
http://msdn.microsoft.com/en-us/library/system.net.ftpwebrequest.aspx
There are examples at the end. Here is a sample taken from msdn:
public static bool DisplayFileFromServer(Uri serverUri)
{
// The serverUri parameter should start with the ftp:// scheme.
if (serverUri.Scheme != Uri.UriSchemeFtp)
{
return false;
}
// Get the object used to communicate with the server.
WebClient request = new WebClient();
// This example assumes the FTP site uses anonymous logon.
request.Credentials = new NetworkCredential ("anonymous","janeDoe#contoso.com");
try
{
byte [] newFileData = request.DownloadData (serverUri.ToString());
string fileString = System.Text.Encoding.UTF8.GetString(newFileData);
Console.WriteLine(fileString);
}
catch (WebException e)
{
Console.WriteLine(e.ToString());
}
return true;
}
This isn't specifically a question as such.
You need to use the socket classes within the .NET framework:
MSDN - System.Net.Sockets
A good example I've previously used is:
www.dreamincode.net - Create an ftp class library
After I use CloudBlob.BeginUploadFromStream() method to upload a file, I later get a StorageClientException with StorageErrorCode.ResourceNotFound when trying to retrieve the file for a download. If I upload the same file using CloudBlob.UploadFromStream() method, then the blob DOES exist and i can download it.
here's my download code:
var client = _storageAccount.CreateCloudBlobClient();
var container = client.GetContainerReference(BLOB_CONTAINER_DOCUMENTS_ADDRESS);
container.CreateIfNotExist();
string blobName = id.ToString();
var newBlob = container.GetBlobReference(blobName);
if (newBlob.Exists())
{
var stream = newBlob.OpenRead();
return stream;
}
else
{
throw new Exception("Blob does not exist!");
}
Exists is an extension method. I'm getting the StorageClientException with the error code ResourceNotFound when I use the BeginUploadFromStream() method
public static bool Exists(this CloudBlob blob)
{
try
{
blob.FetchAttributes();
return true;
}
catch (StorageClientException e)
{
if (e.ErrorCode == StorageErrorCode.ResourceNotFound)
{
return false;
}
else
{
throw;
}
}
}
And my call to upload
var blob = container.GetBlobReference(blobName);
This will NOT throw an exception when i later check if the blob exists
blob.UploadFromStream(fileStream);
This will
AsyncCallback uploadCompleted = new AsyncCallback(OnUploadCompleted);
blob.BeginUploadFromStream(fileStream, uploadCompleted, documentId);
EDIT
As suggested, i didn't have a call to EndUploadFromStream() method. Here is my updated call to upload:
blob.BeginUploadFromStream(fileStream, uploadCompleted, blob);
And my handler
private void OnUploadCompleted(IAsyncResult result)
{
var blob = (CloudBlob) result.AsyncState;
blob.EndUploadFromStream(result);
}
Running this, the EndUploadFromStream() method throws a WebException with the msg: "The request was aborted: The request was canceled." The InnerException is "Cannot close stream until all bytes are written."
Anyone have any idea what's going on here?
BeginUploadFromStream uploads the blob asynchronously, so your method proceeds while the blob uploads on a thread in the background. If the blob hasn't finished uploading -- or if Azure hasn't been told that the upload has completed -- you won't see the blob in storage. Only blobs uploaded through successfully completed transactions are visible.
Could you post the code for OnUploadCompleted?
It looks at first glance as if either the blob is still uploading -- or you've forgotten to call EndUploadFromStream() in your OnUploadCompleted method.
What it sounds like is happening is IIS is cancelling the thread that is being initiated to make the BeginUploadFromStream. Since the storage API is really just manipulating a bunch of REST calls under the hood you can think of these storage calls as web service calls and not like traditional IO.
Check out this topic on HttpKeepAlives, this might solve your problem but as the article pointed out it may impact performance of your site. So you may want to add logic to only enable the keep alive for the requests that are performing the upload.
http://www.jaxidian.org/update/2007/05/05/8/
yes, i know about File.Copy(...), but is there a web service method that can do the same thing? i am also worried about credentials needed to access the server. the inputs are to be the report filepath and the url to the server i want to move the report to WITHOUT CHANGING THE FORMAT. i have been looking at the web service ReportService2005 but not so sure it will work. other web services i have available are: ReportExecution2005, ReportingServices, ReportService, and ReportService2006. i would like to stay away from using rs.exe as well.
// Determine filename without extension (used as name in SSRS)
FileInfo fileInfo = new FileInfo(FileSystemPath);
string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(fileInfo.FullName);
try
{
// Determine filecontents
Byte[] fileContents = File.ReadAllBytes(fileInfo.FullName);
// Publish report
rsService.Warning[] warnings = this.rs.CreateReport(fileNameWithoutExtension, this.SSRSFolder, true, fileContents, null);
if (warnings != null)
{
foreach (rsService.Warning warning in warnings)
{
//Log warnings
}
}
}
catch
{
//handle error
}