Reputation: 34038
ok I have a webapi which gets/adds/updates/deletes customers, the backend is CosmosDB.
Users are able to upload image for each customer, the file is stored in Azure Blob Storage, but the filename is stored in the CosmosDB property.
[HttpPost]
public async Task<IHttpActionResult> Adduser([FromBody]User user)
{
var telemetry = new TelemetryClient();
try
{
var userStore = CosmosStoreHolder.Instance.CosmosStoreUser;
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
//Then we validate the content type
if (!Request.Content.IsMimeMultipartContent("form-data"))
{
throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
}
#region File upload
//Initalize configuration settings
var accountName = ConfigurationManager.AppSettings["storage:account:name"];
var accountKey = ConfigurationManager.AppSettings["storage:account:key"];
var profilepicturecontainername = ConfigurationManager.AppSettings["storage:account:profilepicscontainername"];
//Instance objects needed to store the files
var storageAccount = new CloudStorageAccount(new StorageCredentials(accountName, accountKey), true);
CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
CloudBlobContainer imagesContainer = blobClient.GetContainerReference(profilepicturecontainername);
var provider = new AzureStorageMultipartFormDataStreamProvider(imagesContainer);
// Validate extension and image size
foreach (MultipartFileData file in provider.FileData)
{
var fileName = file.Headers.ContentDisposition.FileName.Trim('\"').Trim();
if (fileName.EndsWith(".png"))
{
var img = Image.FromFile(file.LocalFileName);
if (img.Width != 200 && img.Height != 200)
{
string guid = Guid.NewGuid().ToString();
return BadRequest($"Error Lulo. Unsupported extension, only PNG is valid. Or unsuported image dimensions (200px x 200px)");
}
}
}
//Try to upload file
try
{
await Request.Content.ReadAsMultipartAsync(provider);
}
catch (Exception ex)
{
string guid = Guid.NewGuid().ToString();
var dt = new Dictionary<string, string>
{
{ "Error Lulo: ", guid }
};
telemetry.TrackException(ex, dt);
return BadRequest($"Error Lulo. An error has occured. Details: {guid} {ex.Message}: ");
}
// Retrieve the filename of the file you have uploaded
var filename = provider.FileData.FirstOrDefault()?.LocalFileName;
if (string.IsNullOrEmpty(filename))
{
string guid = Guid.NewGuid().ToString();
var dt = new Dictionary<string, string>
{
{ "Error Lulo: ", guid }
};
return BadRequest($"Error Lulo. An error has occured while uploading your file. Please try again.: {guid} ");
}
//Rename file
CloudBlockBlob blobCopy = imagesContainer.GetBlockBlobReference(user.Id + ".png");
if (!await blobCopy.ExistsAsync())
{
CloudBlockBlob blob = imagesContainer.GetBlockBlobReference(filename);
if (await blob.ExistsAsync())
{
await blobCopy.StartCopyAsync(blob);
await blob.DeleteIfExistsAsync();
}
}
#endregion
if (string.IsNullOrEmpty(user.CustomerId) && string.IsNullOrEmpty(user.PartnerId))
{
return BadRequest("ClientID or PartnerId must be filled in.");
}
var added = await userStore.AddAsync(user);
return Ok(added);
}
catch (Exception ex)
{
string guid = Guid.NewGuid().ToString();
var dt = new Dictionary<string, string>
{
{ "Error Lulo: ", guid }
};
telemetry.TrackException(ex, dt);
return BadRequest("Error Lulo: " + guid);
}
}
Now, I need to return to the web api, the image in someway the frontend developers can render it. The Azure Blob Container is not public, so returning the Url will not be enough.
The front end is react.
This is my get method (which returns the picture Url, only)
[HttpGet]
public async Task<IHttpActionResult> GetUser(string email)
{
var telemetry = new TelemetryClient();
try
{
var userStore = CosmosStoreHolder.Instance.CosmosStoreUser;
var roleStore = CosmosStoreHolder.Instance.CosmosStoreRole;
var user = await userStore.Query().FirstOrDefaultAsync(x => x.EmailAddress == email);
if (user == null)
{
return Unauthorized();
}
var role = await roleStore.Query().FirstOrDefaultAsync(x => x.Id == user.RoleId);
user.RoleName = role.RoleName;
return Ok(user);
}
catch (Exception ex)
{
string guid = Guid.NewGuid().ToString();
var dt = new Dictionary<string, string>
{
{ "Error Lulo: ", guid }
};
telemetry.TrackException(ex, dt);
return BadRequest("Error Lulo: " + guid);
}
}
And just in case, the User POCO here below:
public class User : ISharedCosmosEntity
{
[JsonProperty("Id")]
public string Id { get; set; }
public string EmailAddress { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public bool Enabled { get; set; }
public string ProfilePictureUrl { get; set; }
public string RoleName { get; set; }
public string CustomerName { get; set; }
public string PartnerName { get; set; }
public string CustomerId{ get; set; }
public string PartnerId { get; set; }
public string RoleId { get; set; }
[CosmosPartitionKey]
public string CosmosEntityName { get; set; }
}
Upvotes: 3
Views: 2865
Reputation: 147
This is how I did this in one of my previous project. I have a method that takes the Url path of the picture and the name and extension. The method convert the image to a base64 string.
public string ConvertToBase64(string path)
{
byte[] b = System.IO.File.ReadAllBytes(path);
var base64img = "data:image/jpg;base64," + Convert.ToBase64String(b);
Return base64img;
}
And use it like this.
var imgUrl = AzureImgUrlPath + "imageName.jpg";
var imageBase64String = ConvertToBase64(imgUrl);
Upvotes: 1
Reputation: 455
If you do not have a constant public url to the image, you need to encode it to base64 and embed it as inline image.
If you can access the url inside your POCO from your Web API backend, then you can retrieve and convert the image with the following code:
private static HttpClient _httpClient = new HttpClient();
public async Task<string> GetInlineImageSrcAsync(string url)
{
var bytes = await _httpClient.GetByteArrayAsync(url);
var base64 = Convert.ToBase64String(bytes);
var mimeType = "image/png";
// If mime types differ, try this
// var mimeType = $"image/{ParseExtensionFromUrl(url)}"
var inlineImageSrc = $"data:{mimeType};base64,{base64}";
return inlineImageSrc;
}
public string ParseExtensionFromUrl(string url)
{
return url.Substring(url.LastIndexOf(".") + 1);
}
Note that HttpClient should be static to enable it to reuse connections. This is recommended by Microsoft and boosts performance. More on this:
https://medium.com/@nuno.caneco/c-httpclient-should-not-be-disposed-or-should-it-45d2a8f568bc
https://aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong/
EDIT: This is the HTML to actually embed the image:
<img src="<THE STRING YOU RETURNED>" />
<!-- For Example: -->
<img src="data:image/jpeg;base64,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">
Upvotes: 2
Reputation: 7813
The best way to return a file in Web API is to load it to memory and then return it via the File method:
[HttpGet]
public IActionResult Get()
{
Byte[] b = ...; // Load blob from storage to byte array, usually via a MemoryStream.
return File(b, "image/jpeg");
}
The File method is really a helper that return a FileContentReult or FileStreamResult, you can read motre about it here:
Difference between FileContentResult and FileStreamResult
If you use one of the File method overloads that takes a stream as argument, you can even avoid buffering the entire blob in memory.
Upvotes: 1
Reputation: 9
I'm assuming you're looking to embed the picture in a element? Why don't you use Base64? Then you can return something like:
data:image/[png/jpg depending on image type];base64,[Your Base64 image value here]
Upvotes: 1
Reputation: 1386
You might consider converting the image to base64 string using the approach on: https://www.c-sharpcorner.com/blogs/convert-an-image-to-base64-string-and-base64-string-to-image
Upvotes: 0