[BUG] Upload (PUT) via SAS URI deletes metadata on blob.
See original GitHub issueLibrary name and version
12.11.0
Describe the bug
When creating a blob via BlobClient and setting the metadata, an then obtaining a sas url with write permissions, if I use that uri to upload the blob content, the metadata on the blob is removed.
The file upload via the sas uri works correctly.
Expected behavior
The metadata remains on the blob version.
Actual behavior
the metadata is empty on the blob ( visible through code or the Azure storage Exploer/portal)
Reproduction Steps
using the following code stub to set metadata and createa sas uri. Some code ommitted for brevity.
BlobContainerClient` containerClient = new BlobContainerClient(_storageConnectionString, containerName);
var blobClient = containerClient.GetBlobClient("attachments/" + filePrefix + originalFileName);
//@see https://github.com/Azure/azure-sdk-for-net/issues/10784
if (!blobClient.Exists())
await blobClient.UploadAsync(new System.IO.MemoryStream());
await blobClient.SetMetadataAsync(new Dictionary<string, string> { { ORIGINAL_FILENAME_METADATA_KEY, originalFileName } });
BlobProperties properties = await blobClient.GetPropertiesAsync();
Debug.Assert(properties.Metadata.Any(), "metadata was saved");
var sasURI = GetServiceSasUriForBlob(blobClient, BlobSasPermissions.Write, ip);
Upload code
private static async Task UploadFile(string sasUrl, MemoryStream file, string fileName) {
using (var value = new ByteArrayContent(file.ToArray())) {
value.Headers.Add("x-ms-blob-type", "BlockBlob");
value.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
value.Headers.Add("Content-Disposition", $"form-data; filename=\"{fileName}\"");
// Use a raw client for blobstore and enable compression.
HttpClientHandler handler = new HttpClientHandler();
if (handler.SupportsAutomaticDecompression)
handler.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
var client = new HttpClient(handler);
var upload = await client.PutAsync(sasUrl, value);
if (!upload.IsSuccessStatusCode) {
throw new System.Exception("Failed to upload file : " + upload.ReasonPhrase);
}
}
}
Environment
.NET SDK (reflecting any global.json): Version: 6.0.202 Commit: f8a55617d2
Runtime Environment: OS Name: Windows OS Version: 10.0.19044 OS Platform: Windows RID: win10-x64 Base Path: C:\Program Files\dotnet\sdk\6.0.202\
Host (useful for support): Version: 6.0.4 Commit: be98e88c76
.NET SDKs installed: 6.0.104 [C:\Program Files\dotnet\sdk] 6.0.202 [C:\Program Files\dotnet\sdk]
.NET runtimes installed: Microsoft.AspNetCore.App 3.1.24 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 6.0.4 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.NETCore.App 3.1.24 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 6.0.4 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.WindowsDesktop.App 3.1.24 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App] Microsoft.WindowsDesktop.App 6.0.4 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
To install additional .NET runtimes or SDKs: https://aka.ms/dotnet-download
Issue Analytics
- State:
- Created a year ago
- Comments:6
Top GitHub Comments
The documentation does make it quite clear that metadata gets deleted in a PUT blob request (https://docs.microsoft.com/en-us/rest/api/storageservices/put-blob)
Like @vllama I can’t quite believe this type of feature isn’t supported. It makes a lot of sense to provide SAS uris to clients so that they can upload their files directly to storage instead of proxying them through our own web apps.
The documentation says that you can use Put Block to just upload content but the problem with that is that you then need to call Put Block List to “commit” the changed data. Obviously, that’s leaking the abstraction quite a lot to the client who was just expecting to upload a file to some URI.
The only other option is to give the metadata to the client so that they can add it to the request headers when they upload. That’s now leaky in terms of the data as well as the abstraction.
Thanks for the feedback! We are routing this to the appropriate team for follow-up. cc @xgithubtriage.
Issue Details
Library name and version
12.11.0
Describe the bug
When creating a blob via BlobClient and setting the metadata, an then obtaining a sas url with write permissions, if I use that uri to upload the blob content, the metadata on the blob is removed.
The file upload via the sas uri works correctly.
Expected behavior
The metadata remains on the blob version.
Actual behavior
the metadata is empty on the blob ( visible through code or the Azure storage Exploer/portal)
Reproduction Steps
using the following code stub to set metadata and createa sas uri. Some code ommitted for brevity.
Upload code
Environment
.NET SDK (reflecting any global.json): Version: 6.0.202 Commit: f8a55617d2
Runtime Environment: OS Name: Windows OS Version: 10.0.19044 OS Platform: Windows RID: win10-x64 Base Path: C:\Program Files\dotnet\sdk\6.0.202\
Host (useful for support): Version: 6.0.4 Commit: be98e88c76
.NET SDKs installed: 6.0.104 [C:\Program Files\dotnet\sdk] 6.0.202 [C:\Program Files\dotnet\sdk]
.NET runtimes installed: Microsoft.AspNetCore.App 3.1.24 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 6.0.4 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.NETCore.App 3.1.24 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 6.0.4 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.WindowsDesktop.App 3.1.24 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App] Microsoft.WindowsDesktop.App 6.0.4 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
To install additional .NET runtimes or SDKs: https://aka.ms/dotnet-download
Storage
,Service Attention
,Client
,customer-reported
,question
,needs-team-attention