1

I am creating an Azure blob trigger function for the first time and I find it really strange that the connection string can only be stored inside the Values section of my local.settings.json

public async Task Run([BlobTrigger("container/filename.json", Connection = "TriggerConnectionString")]
        Stream myBlob, ILogger log)

{
  "IsEncrypted": false,
  "Values": {
    "AzureWebJobsStorage": "UseDevelopmentStorage=true",
    "TriggerConnectionString": "myConnectionString"
  },

In another part of my code I am connecting to the same storage account to read a file and perform some action, and to do that I am using IOptions to read a section of my config which you can see below, but because of this trigger I want to add, I will need to have the connection string in two places in my settings.

  "MyStorageSettings": {
    "ConnectionString": "myConnectionString",
    "ContainerName": "myStorageContainerName",
    "FileName": "filename.json"
  }

Is there a way for the connection string in the blob trigger to read from a section in local.settings.json other than the Values section (i.e. the ConnectionString under MyStorageSettings)?

Sukhy
  • 53
  • 8
  • If you need to use the second setting in built-in feature like binding or trigger, then you must put them into the 'Values'. If you dont use built-in feature, then you can parsing the json file to get the value and use them. Please have a look of my answer.:) – Cindy Pau Jul 14 '20 at 10:11
  • The values in 'Values' will be take to the environment variable. Many built-in feature is based on this. – Cindy Pau Jul 14 '20 at 10:14

1 Answers1

1

The value in local.settings.json will be take to environment variable. So if there is something need to get from environment variable, then you must set it in the Values. This is by design, azure function on local doesn't read settings from local.settings.json directly, it read settings from the environment variable.

From your situation, you have two ways to achieve what you want:

1, Let your settings like this:

  "Values": {
    "MyStorageSettings_ConnectionString": "myConnectionString",
    "MyStorageSettings_ContainerName": "myStorageContainerName",
    "MyStorageSettings_FileName": "filename.json"
  }

2, Create your own code to parsing json file.

using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.Text;

namespace HttpTrigger
{
    public static class Function1
    {
        public static string GetFileJson(string filepath)
        {
            string json = string.Empty;
            using (FileStream fs = new FileStream(filepath, FileMode.Open, System.IO.FileAccess.Read, FileShare.ReadWrite))
            {
                using (StreamReader sr = new StreamReader(fs, Encoding.GetEncoding("utf-8")))
                {
                    json = sr.ReadToEnd().ToString();
                }
            }
            return json;
        }
        //Read Json Value
        public static string ReadJson()
        {
            string jsonfile = "custom.json";
            string jsonText = GetFileJson(jsonfile);
            JObject jsonObj = JObject.Parse(jsonText);
            string value = ((JObject)jsonObj["MyStorageSettings"])["ConnectionString"].ToString();
            return value;
        }
        [FunctionName("Function1")]
        public static async Task<IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
            ILogger log)
        {
            string value = ReadJson();

            log.LogInformation("C# HTTP trigger function processed a request.");

            string name = req.Query["name"];

            string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
            dynamic data = JsonConvert.DeserializeObject(requestBody);
            name = name ?? data?.name;

            return name != null
                ? (ActionResult)new OkObjectResult($"Hello, {name}")
                : new BadRequestObjectResult("Please pass a name on the query string or in the request body" + value);
        }
    }
}
Cindy Pau
  • 13,085
  • 1
  • 15
  • 27
  • hey thanks for the fast reply. maybe my question wasn't clear, i'm not having trouble reading from the json file, the problem i'm having is that i can't use MyStorageSettings:ConnectionString as the connection string for the trigger function. i'm restricted to using the Values section which means having the same connection string in the config twice – Sukhy Jul 14 '20 at 10:20
  • @Sukhy So you put `"MyStorageSettings": {...}` in 'Values' directly? But this is not allowed. This will cause function host load the settings failed. Please have a look of this doc:https://learn.microsoft.com/en-us/azure/azure-functions/functions-run-local?tabs=windows%2Ccsharp%2Cbash#local-settings-file Values must be strings and not JSON objects or arrays. Setting names can't include a colon (:) or a double underline (__). These characters are reserved by the runtime. Your structure is not allowed. – Cindy Pau Jul 14 '20 at 10:49
  • hey, no i wasn't going to use the colon in the field, i was just trying to make it clear what value i want to use, i want to use this connection string (myConnectionString) i don't want to use the Values section for my trigger function connection ` "MyStorageSettings": { "ConnectionString": "myConnectionString", "ContainerName": "myStorageContainerName", "FileName": "filename.json" }` – Sukhy Jul 14 '20 at 11:15
  • @Sukhy I think I know that you want now. I didn't mean you are going to use colon in the field, I just copy the description of offcial document. At first, I thought you put the MyStorageSettings in Values section, so I give you the document just want you to notice the environment variable can not be json object. As I metioned in previous comment, trigger dont read connection string from local.settings.json directly. The fact is Values be send to environment variable, and trigger get the settings from envrionment variable. – Cindy Pau Jul 15 '20 at 05:42
  • @Sukhy Have a look of this: https://learn.microsoft.com/en-us/azure/azure-functions/functions-dotnet-class-library#environment-variables Your idea is impossible. – Cindy Pau Jul 15 '20 at 05:44
  • 1
    I had a feeling that was the case. Thanks for your help – Sukhy Jul 15 '20 at 14:43
  • @Sukhy If you don't have more doubts, can you mark my answer to end this question?:) – Cindy Pau Jul 15 '20 at 14:46