我尝试在 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 中,我可以使用以下方式装饰枚举[JsonConverter(typeof(StringEnumConverter))]
从命名空间Newtonsoft.Json
为了实现这一目标。现在这不起作用。
我知道 .Net Core 3 切换到了转换器System.Text.Json
-namespace,所以我尝试用以下内容装饰相同的枚举[JsonConverter(typeof(JsonStringEnumConverter))]
从命名空间System.Text.Json.Serialization
。这也不起作用。
所有其他类似的问题要么说上述应该有效,要么,就像this,说通过配置 JsonOptions 来解决它.AddControllers()
or .AddMvc()
-chain,但是对于一个无法工作的函数应用程序。函数运行时负责设置控制器,因此我们无法直接访问进一步的配置。
使用核心工具的准系统 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
由处理对象结果执行器。我尝试将实现复制到我的解决方案中并将其添加到 DI 容器中,以便我可以调试:
builder.Services.AddSingleton<IActionResultExecutor<ObjectResult>, TestExecutor>();
在链接源的第 101 行,选择了格式化程序。有趣的是,当我此时中断时,选择的格式化程序是NewtonsoftJsonOutputFormatter!我会认为第一个JsonConverter
-attribute 应该适用于此,但事实并非如此。
我认为修改可用输出格式化程序的列表是值得的。 ActionResultExecutor 使用默认输出格式选择器做出选择,然后注入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
- 集合缺少除Microsoft.AspNetCore.Mvc.WebApiCompatShim.HttpResponseMessageOutputFormatter
,这本身很奇怪(为什么一个全新的 3.0 应用程序使用兼容性填充程序?)。
我尝试删除类型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
我们可以在启动时进行配置。
此时,我已经没有线索了,于是转向你们。我希望有人能指出我正确的方向。