I have an ASP.NET MVC 4 app that i want to deploy to Windows Azure. A part of this app involves uploading a picture. When the picture is uploaded, I want to store the pictur
There are some good answers here already that tell you exactly how to do what you need. Allow me to propose an alternative if you don't mind.
Personally, to solve problems such as yours, I turn to Azure Blob Storage. Blob storage is an extremely cheap and fast method of storing binary files (in a folder type structure) completely separate from the VM your cloud service is currently running on.
This will allow you some additional freedom when migrating or developing against your existing application since you don't have to migrate your uploads along with each deployment. Blob storage files are also triple-replicated across multiple Azure datacenters at no additional cost to you and are much more fault tolerant than your deployment VM.
Moving to Blob Storage will also allow you to access your files when your site is offline or your VM is down.
You are no longer operating in the realm of shared computing where all resources must exist on the same machine. Azure was built for scalability and separation of resources. Blob storage was designed specifically for what you are trying to do here.
Here is my as easy as it comes description of how to set this up in azure. http://geekswithblogs.net/MagnusKarlsson/archive/2012/12/02/how-to-use-azure-storage-for-images.aspx
//Edit; heres the complete example from my blog(if the blog dies). yourViewName.cshtml
@model List<string>
@{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<form action="@Url.Action("Upload")" method="post" enctype="multipart/form-data">
<label for="file">Filename:</label>
<input type="file" name="file" id="file1" />
<br />
<label for="file">Filename:</label>
<input type="file" name="file" id="file2" />
<br />
<label for="file">Filename:</label>
<input type="file" name="file" id="file3" />
<br />
<label for="file">Filename:</label>
<input type="file" name="file" id="file4" />
<br />
<input type="submit" value="Submit" />
</form>
@foreach (var item in Model) {
<img src="@item" alt="Alternate text"/>
}
Your controller action
public ActionResult Upload(IEnumerable<HttpPostedFileBase> file)
{
BlobHandler bh = new BlobHandler("containername");
bh.Upload(file);
var blobUris=bh.GetBlobs();
return RedirectToAction("Index",blobUris);
}
Your model
public class BlobHandler
{
// Retrieve storage account from connection string.
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(
CloudConfigurationManager.GetSetting("StorageConnectionString"));
private string imageDirecoryUrl;
/// <summary>
/// Receives the users Id for where the pictures are and creates
/// a blob storage with that name if it does not exist.
/// </summary>
/// <param name="imageDirecoryUrl"></param>
public BlobHandler(string imageDirecoryUrl)
{
this.imageDirecoryUrl = imageDirecoryUrl;
// Create the blob client.
CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
// Retrieve a reference to a container.
CloudBlobContainer container = blobClient.GetContainerReference(imageDirecoryUrl);
// Create the container if it doesn't already exist.
container.CreateIfNotExists();
//Make available to everyone
container.SetPermissions(
new BlobContainerPermissions
{
PublicAccess = BlobContainerPublicAccessType.Blob
});
}
public void Upload(IEnumerable<HttpPostedFileBase> file)
{
// Create the blob client.
CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
// Retrieve a reference to a container.
CloudBlobContainer container = blobClient.GetContainerReference(imageDirecoryUrl);
if (file != null)
{
foreach (var f in file)
{
if (f != null)
{
CloudBlockBlob blockBlob = container.GetBlockBlobReference(f.FileName);
blockBlob.UploadFromStream(f.InputStream);
}
}
}
}
public List<string> GetBlobs()
{
// Create the blob client.
CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
// Retrieve reference to a previously created container.
CloudBlobContainer container = blobClient.GetContainerReference(imageDirecoryUrl);
List<string> blobs = new List<string>();
// Loop over blobs within the container and output the URI to each of them
foreach (var blobItem in container.ListBlobs())
blobs.Add(blobItem.Uri.ToString());
return blobs;
}
}
Data and images are not meant to be stored in website directory. That's why there is the Azure Blob Storage.
Azure works by copying the website out to an instance, so if more than one instance exists then uploaded images (which are stored local to the instance) will become out of sync, you will even loose images if there are conflicts.
If you really want to do it the line below will give you what you want:
string path = Server.MapPath("~/pictures/uploaded");
string path = HostingEnvironment.MapPath(@"~/pictures/uploaded");