Pandora Pocket

IT系と日常系の備忘録。三日坊主。

AzureFunctionsのlocal.settings.jsonファイルといえば

 {  
   "IsEncrypted": false,  
   "Values": {  
     "FUNCTIONS_WORKER_RUNTIME": "<language worker>",  
     "AzureWebJobsStorage": "<connection-string>",  
     "AzureWebJobsDashboard": "<connection-string>",  
     "MyBindingConnection": "<binding-connection-string>"  
   },  
   "Host": {  
     "LocalHttpPort": 7071,  
     "CORS": "*"  
   },  
   "ConnectionStrings": {  
     "SQLConnectionString": "<sqlclient-connection-string>"  
   }  
 }  

Azure Functionsを Azure Functions で実行する前に、ローカル コンピューターのコマンド プロンプトまたはターミナルでコーディングしてテストする方法について説明します。
[はてなブックマークで表示]

のような感じで設定情報が保存されてます。

今回Valuesに新たに追加する際、

   "Values": {  
     "FUNCTIONS_WORKER_RUNTIME": "<language worker>",  
     "AzureWebJobsStorage": "<connection-string>",  
     "AzureWebJobsDashboard": "<connection-string>",  
     "MyBindingConnection": "<binding-connection-string>",  
     "NewParam": {  
       "NewKey1": "NewParameter1",  
       "NewKey2": "NewParameter2",  
     }  
   },  

こんな感じで、階層を持たせた形で追加したのですが、これでAzure Functionsを起動すると、

Missing value for AzureWebJobsStorage in local.settings.json. This is required for all triggers other than HTTP. You can run 'func azure functionapp fetch-app-settings ' or specify a connection string in local.settings.json.

こんな感じでエラーを吐いて動かない。

Azure FunctionsのGitHubに本件についてIssueがありまして、

Hey guys, I'm still having issues debugging locally with the local.settings.json and AzureWebJobsStorage - I'm not sure if that one is the real issue or the error is a different one but the excepti...
[はてなブックマークで表示]

こちらによると、

Values collection is expected to be a Dictionary<string, string> and it's failing to parse it and returning an empty dictionary. I think parsing it as a JObject and displaying an error for any non-string values would be more correct here.

I know it's a bit confusing with the .NET Core appsettings.json, but this file local.settings.json is meant to just be a local equivalent to the Azure App Settings which are just key-value pairs.

ということで、 Dictionary<string, string>として保持する関係で、階層的に値を持たせることができないらしい。
なんてこったい。

なので上記のようなJSONだと、

  "Values": {  
    "FUNCTIONS_WORKER_RUNTIME": "<language worker>",  
    "AzureWebJobsStorage": "<connection-string>",  
    "AzureWebJobsDashboard": "<connection-string>",  
    "MyBindingConnection": "<binding-connection-string>",  
    "NewParam:NewKey1": "NewParameter1"  
    "NewParam:NewKey2": "NewParameter2"  
  },  

として持たせる方法をとるくらいしかなさそうです。

まぁ確かにAzureポータル上では結局こういう風に値をセットすることになりますし、階層で持たせるようなことはあまりしないのかも・・・?

ただ、エラーメッセージが分かりにくい。

Missing value for AzureWebJobsStorage in local.settings.json.

これだとAzureWebJobsStorage のKeyが登録されてないという風にしか読めないです。上記の仕様でパースができなかった結果Valueが取得できなかったためのエラーなんでしょうけども。

以上、JSONの規格上は正しくても、Azure Functionsでは動かないという罠でした。