【问题标题】:Azure Functions 2 - How to control json serialization settingsAzure Functions 2 - 如何控制 json 序列化设置
【发布时间】: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 管道扩展,从而实现这一目标。

标签: azure json.net azure-functions


【解决方案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 类型。希望在未来我们将获得更好的集成/注入故事。

【讨论】:

    猜你喜欢
    • 2018-04-05
    • 1970-01-01
    • 1970-01-01
    • 2011-07-05
    • 1970-01-01
    • 1970-01-01
    • 2014-03-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多