Azure Functions 2 - 如何控制 json 序列化设置

Posted

技术标签:

【中文标题】Azure Functions 2 - 如何控制 json 序列化设置【英文标题】:Azure Functions 2 - How to control json serialization settings 【发布时间】:2019-04-15 08:06:42 【问题描述】:

当我从 Azure 函数 (V2) 返回内容结果时,我希望能够控制 json 的格式。以下是我正在做的简化版本:

[FunctionName("CreateThing")]
public static async Task<IActionResult> CreateThingAsync([HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = "thing")]HttpRequest req, ILogger log)

    try
        var result = await GetResultAsync(req);
        return new CreatedResult($"thing/result.id", result);
    
    catch(ErrorException) 
        return new BadRequestObjectResult(e.Error);
    

有没有一种方法可以控制返回时结果的格式,而不使用我的模型上的属性?我希望能够使用 JsonSerializerSettings,但我找不到一种方法可以为根据上面示例返回的结果配置它。

【问题讨论】:

你试过JsonResult 和 JsonSerializerSettings 吗? JsonResult 与 JsonSerialiserSettings 可以工作,但它不允许设置状态代码或开箱即用的其他响应标头。理想情况下,我可以在其他地方设置 Json 格式化的职责。如果这是一个 MVC 应用程序,那就很简单了。功能应用程序似乎通过更少的扩展挂钩给了我很多控制。 Github 中的 AzureFunctions 存储库中有一个(已关闭)问题,有人描述了如何通过从 HttpRequest 对象创建响应来做到这一点。 github.com/Azure/Azure-Functions/issues/298 感谢@SebastianAchatz。我可能不得不做类似的事情。遗憾的是,在它离开静态函数方法后,没有办法挂钩函数响应。我最终可能会创建一些可以将所有 ObjectResult 映射到 JsonResult 的东西,只是为了使用允许我设置 JsonSerializerSettings 的覆盖。 环顾四周后,我认为这种情况可能会在即将发布的 Azure Function SDK/API 中得到解决。依赖注入即将推出 - 希望 Azure 函数团队能够借此机会公开 WebJobs 管道扩展,从而实现这一目标。 【参考方案1】:

我自己今天也遇到了同样的问题。

正如 Jerry 所评论的,JsonResult 可以帮助您完成大部分工作;它支持StatusCode 属性:

return new JsonResult(new WorkQueuedResponseMessage

    ...
, Constants.CommunicationJsonSerializerSettings)

    StatusCode = StatusCodes.Status202Accepted,
;

对于自定义标头,我的解决方案有点老套。我定义了自己的IActionResult,它只是将标题粘贴到另一个IActionResult

private sealed class HeaderActionResult : IActionResult

    private readonly IActionResult _result;

    public HeaderActionResult(IActionResult result)
    
        _result = result;
        HeaderDictionary = new HeaderDictionary();
        Headers = new ResponseHeaders(HeaderDictionary);
    

    public IHeaderDictionary HeaderDictionary  get; 

    public ResponseHeaders Headers  get; 

    public async Task ExecuteResultAsync(ActionContext context)
    
        foreach (var header in HeaderDictionary)
            context.HttpContext.Response.Headers.Append(header.Key, header.Value);
        await _result.ExecuteResultAsync(context);
    

如果需要,我可以定义辅助方法:

public static IActionResult EnableCacheHeaders(this IActionResult response, TimeSpan time)

    return new HeaderActionResult(response)
    
        Headers =
        
            CacheControl = new CacheControlHeaderValue
            
                Public = true,
                MaxAge = time,
            ,
            Expires = DateTimeOffset.UtcNow + time,
        ,
    ;

并像这样使用它们:

return new JsonResult(new WorkAlreadyCompletedResponseMessage

    ...
, Constants.CommunicationJsonSerializerSettings).EnableCacheHeaders(TimeSpan.FromDays(1));

这是一种使用自定义 JSON 序列化、状态代码和标头返回 IActionResult 的方式,同时使用尽可能多的 ASP.NET Core 类型。希望在未来我们将获得更好的集成/注入故事。

【讨论】:

以上是关于Azure Functions 2 - 如何控制 json 序列化设置的主要内容,如果未能解决你的问题,请参考以下文章

Azure Functions 2.0:如何从命令提示符启动项目并允许从其他计算机连接?

如何从 Azure 移动应用服务调用 HTTP(Azure Functions)?

Azure Functions:如何在 Azure 存储队列的绑定表达式中使用 POCO?

如何使用应用服务对 Azure Functions 应用进行身份验证/授权?

如何使用 Azure Functions 检查授权

更新到 Microsoft.Net.Functions 3.0.3 后如何正确设置 Azure 队列触发器?