使用Azure Functions 3.0中的属性将Enum序列化为字符串 [英] Serializing Enum as string using attribute in Azure Functions 3.0
问题描述
我曾尝试在Azure Functions 3.0/3.1应用程序中使用HTTP触发器来返回枚举的字符串表示形式,但没有成功。酷睿3.0和酷睿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 Core2中,我可以使用命名空间Newtonsoft.Json
中的[JsonConverter(typeof(StringEnumConverter))]
来修饰枚举来实现这一点。这现在不起作用。
我知道.Net Core3切换到System.Text.Json
-命名空间中的转换器,因此我尝试使用命名空间System.Text.Json.Serialization
中的[JsonConverter(typeof(JsonStringEnumConverter))]
装饰相同的枚举。这也不起作用。
所有其他类似的问题要么说上面应该可以工作,要么像this说要通过在.AddControllers()
或.AddMvc()
链中配置JsonOptions来解决它,但对于一个不能工作的函数应用程序。函数运行时负责设置控制器,因此我们无法直接访问进一步的配置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
-属性应该对此起作用,但它不起作用。
我认为值得一试修改可用的输出格式化程序列表。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
集合缺少除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
。我以前从来没有遇到过这种情况。通常,包是暂时依赖的,所以我可以引用它,而不是自己显式地依赖于包,所以我不太确定这里发生了什么。这是正常的吗,还是我的环境有问题?
当我以另一种方式删除它时,它无关紧要,无论如何它都被选中了,因此DefaultOutputFormatterSelector
中注入的MvcOptions
似乎与我们在启动时可以配置的MvcOptions
不同。
在这一点上,我没有线索了,于是求助于你们。我希望有人能为我指明正确的方向。
推荐答案
我还遇到了.NET Core3.1函数应用程序的序列化问题。建议我使用此应用程序设置作为临时解决方法:
"FUNCTIONS_V2_COMPATIBILITY_MODE": true
这解决了我的issue。
这篇关于使用Azure Functions 3.0中的属性将Enum序列化为字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!