Reputation: 45
Getting http 400, when trying to upload an image to blob, using postman to test the api:
[Route("~/api/myAPI/testapi")]
[HttpPost]
public async Task<HttpResponseMessage> testapi()
{
String strorageconn = System.Configuration.ConfigurationManager.AppSettings.Get("MyBlobStorageConnectionString");
Dictionary<string, object> dict = new Dictionary<string, object>();
try
{
// Create a CloudStorageAccount object using account name and key.
// The account name should be just the name of a Storage Account, not a URI, and
// not including the suffix. The key should be a base-64 encoded string that you
// can acquire from the portal, or from the management plane.
// This will have full permissions to all operations on the account.
// StorageCredentials storageCredentials = new StorageCredentials(myAccountName, myAccountKey);
//CloudStorageAccount cloudStorageAccount = new CloudStorageAccount(storageCredentials, useHttps: true);
// Parse the connection string and return a reference to the storage account.
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(strorageconn);
// If the connection string is valid, proceed with operations against Blob
// storage here.
// ADD OTHER OPERATIONS HERE
// Create the CloudBlobClient that represents the
// Blob storage endpoint for the storage account.
CloudBlobClient cloudBlobClient = storageAccount.CreateCloudBlobClient();
// Create a container called 'quickstartblobs' and
// append a GUID value to it to make the name unique.
CloudBlobContainer cloudBlobContainer = cloudBlobClient.GetContainerReference("images");
//"quickstartblobs" + Guid.NewGuid().ToString());
await cloudBlobContainer.CreateAsync();
if (cloudBlobContainer.CreateIfNotExists())
{
cloudBlobContainer.SetPermissions(
new BlobContainerPermissions
{
PublicAccess = BlobContainerPublicAccessType.Blob
});
}
// Set the permissions so the blobs are public.
/* BlobContainerPermissions permissions = new BlobContainerPermissions
{
PublicAccess = BlobContainerPublicAccessType.Blob
};
await cloudBlobContainer.SetPermissionsAsync(permissions); */
// Create a CloudBlobClient object from the storage account.
// This object is the root object for all operations on the
// blob service for this particular account.
//CloudBlobClient blobClient = cloudStorageAccount.CreateCloudBlobClient();
var httpRequest = HttpContext.Current.Request;
foreach (string file in httpRequest.Files)
{
HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.Created);
var postedFile = httpRequest.Files[file];
// Get a reference to a CloudBlobContainer object in this account.
// This object can be used to create the container on the service,
// list blobs, delete the container, etc. This operation does not make a
// call to the Azure Storage service. It neither creates the container
// on the service, nor validates its existence.
string imageName = "images" +serverTime.Year.ToString() + serverTime.Month.ToString() + serverTime.Day.ToString() +
serverTime.Hour.ToString() + serverTime.Minute.ToString() + serverTime.Second.ToString ()
+ postedFile.FileName.ToLower();
//CloudBlobContainer container = blobClient.GetContainerReference(imageName.ToLower());
/*if(await container.CreateIfNotExistsAsync())
{
await container.SetPermissionsAsync(
new BlobContainerPermissions {
PublicAccess = BlobContainerPublicAccessType.Blob
}
);
} */
if (postedFile != null && postedFile.ContentLength > 0)
{
int MaxContentLength = 1024 * 1024 * 1; //Size = 1 MB
IList<string> AllowedFileExtensions = new List<string> { ".jpg", ".gif", ".png" };
var ext = postedFile.FileName.Substring(postedFile.FileName.LastIndexOf('.'));
var extension = ext.ToLower();
if (!AllowedFileExtensions.Contains(extension))
{
var message = string.Format("Please Upload image of type .jpg,.gif,.png.");
dict.Add("error", message);
return Request.CreateResponse(HttpStatusCode.BadRequest, dict);
}
else if (postedFile.ContentLength > MaxContentLength)
{
var message = string.Format("Please Upload a file upto 1 mb.");
dict.Add("error", message);
return Request.CreateResponse(HttpStatusCode.BadRequest, dict);
}
else
{
var filePath = HttpContext.Current.Server.MapPath("~/imagesfiles/uploads" + postedFile.FileName.ToLower() + extension.ToLower());
postedFile.SaveAs(filePath);
//CloudBlockBlob cloudBlockBlob = container.GetBlockBlobReference(imageName);
// Get a reference to the blob address, then upload the file to the blob.
// Use the value of localFileName for the blob name.
CloudBlockBlob cloudBlockBlob = cloudBlobContainer.GetBlockBlobReference(imageName.ToLower());
// create a blob in container and upload image bytes to it
//var blob =container.GetBlobReference(postedFile.FileName);
await cloudBlockBlob.UploadFromFileAsync(postedFile.FileName);
//await cloudBlockBlob.UploadFromFileAsync(filePath);
}
}
var message1 = string.Format("Image Updated Successfully.");
return Request.CreateErrorResponse(HttpStatusCode.Created, message1); ;
}
var res = string.Format("Please Upload a image.");
dict.Add("error", res);
return Request.CreateResponse(HttpStatusCode.NotFound, dict);
}
catch (Exception ex)
{
HttpResponseMessage response2 = Request.CreateResponse(HttpStatusCode.BadRequest, ex.InnerException.ToString());
return response2;
}
}
Response from postman:
"System.Net.WebException: The remote server returned an error: (400) Bad Request.\r\n at Microsoft.Azure.Storage.Shared.Protocol.HttpResponseParsers.ProcessExpectedStatusCodeNoException[T](HttpStatusCode expectedStatusCode, HttpStatusCode actualStatusCode, T retVal, StorageCommandBase`1 cmd, Exception ex)\r\n at Microsoft.Azure.Storage.Blob.CloudBlobContainer.<>c_DisplayClass149_0.<CreateContainerImpl>b_2(RESTCommand`1 cmd, HttpWebResponse resp, Exception ex, OperationContext ctx)\r\n at Microsoft.Azure.Storage.Core.Executor.Executor.EndGetResponse[T](IAsyncResult getResponseResult)"
Upvotes: 0
Views: 834
Reputation: 45
Thanks to Pamela Peng, i was able to face different exception and find the issue.
First issue was the version, so i change to visual studio 2019, and had to add correct reference. and the other issue was in code so i updated the else with:
else
{
CloudBlockBlob cloudBlockBlob = cloudBlobContainer.GetBlockBlobReference(imageName);
cloudBlockBlob.Properties.ContentType = postedFile.ContentType;
await cloudBlockBlob.UploadFromStreamAsync(postedFile.InputStream);
}
Upvotes: 1
Reputation: 7473
Not sure why it does not work, the code looks correct. The error occurs in many cases.
If you request a container with an invalid name, it will result in (400) Bad Request, which you are getting. It has some limitations about the container name, so check your string.
If the blob storage emulator would not start, it will return 400 Bad Request. see here.
If the versions of the storage libraries and storage emulator are out of sync, it will also return 400 Bad Request, see here.
Last, the location of your storage may matter, see here.
Upvotes: 1