azure-functions-host
azure-functions-host copied to clipboard
Blob bindings can't set ContentType and other properties
The blob output binding feature set always application/octet-stream to ContentType property. If possible, I would like to modified some blob properties.
And, Just now I don't found documents about some bindings. Example, Blob output binding can use %rand-guid%. And file name placeholder can use {name} from input binding.
I want to know details about bindings.
This is definitely an issue. It would be helpful to know if you're trying to use C#/Node. Could just share a code sample with us?
We have a variety of ideas for how to make this smoother. We'd appreciate your input on how you'd like to set the Content Type, as well.
Example: https://gist.github.com/buchizo/2f8ac640a21cd78920eccbfd7e0d267d
If I use CloudBlockBlob, I can set ContentType property. But it's not easily.
Agreed that you shouldn't have to use CloudBlockBlob - we should aim to make this work cross language, which means using generic types.
We should think through how we'd design this.
I think this is related to binding data improvements we've had in mind for node.
Another related issue here: https://github.com/Azure/azure-webjobs-sdk-script/issues/465. In general, we want to allow "object" bindings. I.e., allow a user to specify dataType: "object"
in their binding metadata, which we translate to a JObject binding on the extension, with the extension handling the mapping from Blob/EventData => JObject, which can then be exposed to script.
Any progress on being able to configure the content/mimetype when the output type is "blob" in Azure functions?
Not yet - we'll get to it :)
Cool looking forward to it :D
Found this after making my feature request in #1664.
There, I specified that I would like to be able to set properties to static values like this:
{
"name": "outOutputBlob",
"type": "blob",
"direction": "out",
"path": "{container}/{blob}",
"connection": "AZURE_STORAGE_CONNECTION_STRING",
"properties": {
"cacheControl": "public, max-age 86400",
"contentType": "application/json",
"contentEncoding": "gzip"
}
}
Maybe to set the value at runtime:
context.bindings.outputBlob = {data: '...'};
context.bindingsMetadata.outputBlob.properties = {contentType:'application/json'};
Is there any progress on this?
No progress on this yet. Right now our main priority for JavaScript is getting the new out-of-proc model used in functions V2 to have feature and behavior parity with V1. Switching from Edge.js to a seperate node.exe process communicating over grpc is a pretty large change with a tail of bugs that will impact users trying to upgrade to V2 if not fixed.
Thank you Paul,
I finally resolved it using Azure storage SDK:
var azure = require('azure-storage');
var streamifier = require('streamifier');
var options = {contentSettings:{contentType:'application/xml'}}
content_stream = streamifier.createReadStream("content");
var blobService = azure.createBlobService("DefaultEndpointsProtocol=https;AccountName=.....");
content_stream.pipe(blobService.createWriteStreamToBlockBlob(container, outputFileName, options, function(error, result, response){...}
any update on this issues?
My comment above still reflects the current state.
This is one of the solutions for upload image and set the adequate mime - content type https://github.com/nemanjamil/azure-functions/blob/master/azure_upload_image.js
This basically means that the example from the docs (repeated twice) doesn't work. For some files (e.g. text/html), it copies the contents but breaks the content type. For others (e.g. png), it breaks the content too: I got the encoding messed up and a "copy" file is twice as long.
Tested with these bindings:
{"disabled":false,"bindings":[
{"authLevel":"anonymous","type":"httpTrigger","direction":"in","name":"req","route":"{name}"},
{"type":"http","direction":"out","name":"response"},
{"name":"original","type":"blob","direction":"in","path":"files/{name}","connection":"StorageConnectionStringKey"},
{"name":"copy","type":"blob","direction":"out","path":"files/copy-{name}","connection":"StorageConnectionStringKey"}
]}
still not possible? that's a bummer
Is there any progress on this? Thanks
Any updates on this? Would like to set properties on a Service Bus binding.
any updates on this?
any update?
2021 and still waiting for this feature.
Any chance you we can get an update?
5 Years have passed!
👀
Just came across this issue. It also applied to the new isolated process model for C# as well. Any news?
This is how Jeff Hollan solved it for me https://github.com/shanselman/azurefridayaggregator/pull/1/files
It's not clean, but it works. I would prefer that I be able to set the content type more readily in a single line.
On Sat, Jan 8, 2022 at 1:22 PM Adam Storr @.***> wrote:
Just came across this issue. It also applied to the new isolated process model for C# as well. Any news?
— Reply to this email directly, view it on GitHub https://github.com/Azure/azure-functions-host/issues/364#issuecomment-1008157025, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAAAWTBDL24O5H3LCKAYLTLUVCTIHANCNFSM4CEKPBKA . You are receiving this because you commented.Message ID: @.***>
@shanselman thanks for sharing the link. The Blob bindings in the new isolated model don't give those options unfortunately. I guess the only option will be to inject a BlockBlobClient
manually through DI and save it that way instead of an BlobOutput
binding.
What I ended up doing was not using the binding at all.
- Registering the BlobServiceClient in
ConfigureServices
services.AddAzureClients(builder =>
{
builder.AddBlobServiceClient(hostContext.Configuration["AzureWebJobsStorage"]);
});
-
Injecting into the azure function, through dependency injection, a
BlobServiceClient
. -
In the timer function method getting a Blob Container Client.
var containerClient = _blobServiceClient.GetBlobContainerClient("my-blob-name");
- Creating a BlockBlobClient from the Container client.
var blockClient = containerClient.GetBlockBlobClient("blob-name.json");
- Writing the data to a stream and uploading it like @shanselman example.
Stream jsonStream = new MemoryStream();
await JsonSerializer.SerializeAsync(jsonStream, mydata, new JsonSerializerOptions() { WriteIndented = true });
jsonStream.Position = 0;
await blockClient.UploadAsync(jsonStream, new BlobHttpHeaders() { ContentType = "application/json" });
Hope this helps others.