Azure Functions 3.0/3.1アプリでHTTPトリガーを取得して、運のない列挙型の文字列表現を返すことを試みました。 Core 3.0とCore 3.1の両方を試しました。
このクラスを考えると:
_public enum TestEnum
{
TestValue
}
public class TestClass
{
public TestEnum Test { get; set; }
}
_
私はこのHTTPトリガーを期待します:
_[FunctionName("MyHttpTrigger")]
public static IActionResult Run(
[HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req, ILogger log)
{
return new OkObjectResult(new TestClass { Test = TestEnum.TestValue });
}
_
_{ "test": "TestValue" }
_を返します。代わりに、_{ "test": 0 }
_を返します。
.Net Core 2では、名前空間_Newtonsoft.Json
_から[JsonConverter(typeof(StringEnumConverter))]
を使用して列挙型を装飾し、これを実現できました。これは現在機能しません。
.Net Core 3が_System.Text.Json
_- namespaceでコンバーターに切り替えたことを知っているので、名前空間_System.Text.Json.Serialization
_から[JsonConverter(typeof(JsonStringEnumConverter))]
で同じ列挙型を修飾してみました。これも機能しませんでした。
他のすべての同様の問題は、上記が機能するか、または this のように、.AddControllers()
または.AddMvc()
でJsonOptionsを構成して解決することを示しています-chain、ただし機能しない機能アプリの場合。関数ランタイムはコントローラーのセットアップを担当するため、追加の構成AFAIKに直接アクセスすることはできません。
この問題は、コアツールを使用した最小限のAzure Functionsプロジェクトで再現可能です。
_func init MyFunctionProj
cd MyFunctionProj
func new --name MyHttpTrigger --template "HttpTrigger"
_
次に、httpトリガーを変更して、内部に列挙型を持つオブジェクトを返します。
私のバージョン:
_> func --version
3.0.1975
> dotnet --version
3.1.100
_
私は複数の回避策を試しましたので、ここに私の観察の一部を示します。 OkObjectResult
は ObjectResultExecutor によって処理されます。実装を自分のソリューションにコピーし、DIコンテナーに追加してデバッグできるようにしました:
_builder.Services.AddSingleton<IActionResultExecutor<ObjectResult>, TestExecutor>();
_
リンクされたソースの101行目で、フォーマッタが選択されています。興味深いことに、この時点で中断すると、選択されたフォーマッターは NewtonsoftJsonOutputFormatter !になります。最初のJsonConverter
- attributeはこれで動作するはずですが、動作しません。
使用可能な出力フォーマッターのリストを変更するのは一見の価値があると思いました。 ActionResultExecutorは DefaultOutputFormatterSelector を使用して選択を行い、次に_IOptions<MvcOptions>
_を挿入して出力フォーマッターを取得します。
DefaultOutputFormatterSelector
に異なる選択を強制するために、私はこれを試しました:
_class MvcOptionsConfiguration : IPostConfigureOptions<MvcOptions>
{
...
}
public class Startup : FunctionsStartup
{
public override void Configure(IFunctionsHostBuilder builder)
{
builder.Services.ConfigureOptions<MvcOptionsConfiguration>();
}
}
_
通常の_IConfigureOptions<T>
_は、_options.Outputformatters
_- collectionには_Microsoft.AspNetCore.Mvc.WebApiCompatShim.HttpResponseMessageOutputFormatter
_以外のすべてのフォーマッターが欠落していたため、使用できなかったことに注意してください。これは、それ自体が奇妙です(なぜ、互換性シム?).
タイプNewtonsoftJsonOutputFormatter
をコレクションから削除しようとしました:
_options.OutputFormatters.RemoveType<NewtonsoftJsonOutputFormatter>();
_
そのためには、nugetパッケージ_Microsoft.AspNetCore.Mvc.NewtonsoftJson
_を参照して型にアクセスする必要がありましたが、参照したときの型は、ランタイムで使用される型とは異なりました。ランタイムで使用される型の_type.Assembly.CodeBase
_は_%USERPROFILE%/AppData/Local/AzureFunctionsTools/
_にありましたが、nugetからの型は_Project root/bin/Debug
_にありました。私はこれにこれまで遭遇したことがありません。通常、パッケージは一時的な依存関係になるため、自分で明示的にパッケージに依存せずに参照できるため、ここで何が行われているのか本当にわかりません。これは正常ですか、それとも私の環境に問題がありますか?
別の方法でそれを削除したとき、それは問題ではなく、とにかく選択されたので、MvcOptions
に注入されたDefaultOutputFormatterSelector
は同じではないようですMvcOptions
スタートアップで。
この時点で、私はリードを使い果たして、あなたたちに向けました。私を正しい方向に向けてくれる人がいるといいのですが。
私は次のコードを使用してこれを機能させることができました
using Microsoft.Azure.Functions.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection;
using Newtonsoft.Json.Converters;
[Assembly: FunctionsStartup(typeof(Configs.Startup))]
namespace Configs
{
class Startup : FunctionsStartup
{
public override void Configure(IFunctionsHostBuilder builder)
{
builder.Services.AddMvcCore().AddNewtonsoftJson(x =>
{
x.SerializerSettings.Converters.Add(new StringEnumConverter());
});
}
}
}
これは、Azure Functions Core Tools(3.0.2534 Commit hash:bc1e9efa8fa78dd1a138dd1ac1ebef97aac8d78e)のnetcoreapp3.1および次のパッケージを含むFunction Runtime Version:3.0.13353.0にありました。
<PackageReference Include="AsyncEnumerator" Version="4.0.2" />
<PackageReference Include="AzureFunctions.Autofac" Version="4.0.0" />
<PackageReference Include="CsvHelper" Version="15.0.5" />
<PackageReference Include="Dapper" Version="2.0.35" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="3.1.4" />
<PackageReference Include="Microsoft.Azure.Functions.Extensions" Version="1.0.0" />
<PackageReference Include="Microsoft.NET.Sdk.Functions" Version="3.0.7" />
<PackageReference Include="System.Data.SqlClient" Version="4.8.1" />
うまくいけば、これは誰かを助けます。
ここにサンプルのリポジトリをプッシュしました: https://github.com/rawrspace/string-enum-example
編集:今日も同じ設定でこれを使用しており、[JsonConverter(typeof(StringEnumConverter))]を使用すると完全に問題なく動作しました。最近更新が行われたかどうかはわかりませんが、念のため上記のソリューションは残しておきます。