客户要求ASP.NET Core API返回特定格式,怎么办?(续2)

Posted dotNET跨平台

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了客户要求ASP.NET Core API返回特定格式,怎么办?(续2)相关的知识,希望对你有一定的参考价值。

前言

前2次,我们都是假设客户需要返回不同的字符串格式。

但是,有可能客户要求的返回是非本文格式,比如文件流。

怎么办?

思路

前提,当然还是使用同一API接口,不影响现有使用方式。

虽然ASP.NET Core Web API默认使用SystemTextJsonOutputFormatter格式化响应,但是OutputFormatters集合里其实包含了StreamOutputFormatter

那么实现目标就转化为,怎么让Web API使用StreamOutputFormatter

DefaultOutputFormatterSelector

通过查看dotnet/aspnetcore源代码,我们找到了DefaultOutputFormatterSelector,它是选择IOutputFormatter以写入对当前请求的响应的默认实现:

其中,选择IOutputFormatter具体实现是通过判断CanWriteResult方法,代码如下:

foreach (var formatter in formatters)

    formatterContext.ContentType = new StringSegment();
    formatterContext.ContentTypeIsServerDefined = false;

    if (formatter.CanWriteResult(formatterContext))
    
        return formatter;
    

StreamOutputFormatter是这样实现CanWriteResult方法的:

public bool CanWriteResult(OutputFormatterCanWriteContext context)

    if (context == null)
    
        throw new ArgumentNullException(nameof(context));
    

    // Ignore the passed in content type, if the object is a Stream.
    if (context.Object is Stream)
    
        return true;
    

    return false;

那么实现目标就转化为,怎么让Web API返回的是Stream

操作返回类型

微软官方文档ASP.NET Core Web API 中控制器操作的返回类型[1]提到,返回类型除了支持特定类型之外,还支持ActionResult<T>

ActionResult<T>可以返回从ActionResult派生的类型或返回特定类型:

那么实现目标就转化为,将返回类型设为ActionResult<T>,根据条件返回T,或者返回特定ActionResult派生类,例如FileResult

实现

具体实现代码如下,如果Accept Headertext/json则返回文件流:

[HttpGet]
public ActionResult<IEnumerable<WeatherForecast>> Get()

    var rng = new Random();
    var result = Enumerable.Range(1, 5).Select(index => new WeatherForecast
    
        Date = DateTime.Now.AddDays(index),
        TemperatureC = rng.Next(-20, 55),
        Summary = Summaries[rng.Next(Summaries.Length)]
    )
    .ToArray();

    HttpContext.Request.Headers.TryGetValue("Accept", out var acceptValue);
    if (acceptValue.ToString() == "text/json")
    
        using (var memory = new MemoryStream())
        
            using (var writer = new StreamWriter(memory))
            
                writer.Write(System.Text.Json.JsonSerializer.Serialize(result));
                writer.Flush();
            

            return File(memory.ToArray(), "text/json", "WeatherForecast.json");
         
    

    return result;

结论

现在,只需要客户在每个API请求加上Accept Header即可满足需求。

如果你觉得这篇文章对你有所启发,请关注我的个人公众号”My IO“

参考资料

[1]

ASP.NET Core Web API 中控制器操作的返回类型: https://docs.microsoft.com/zh-cn/aspnet/core/web-api/action-return-types?view=aspnetcore-5.0

以上是关于客户要求ASP.NET Core API返回特定格式,怎么办?(续2)的主要内容,如果未能解决你的问题,请参考以下文章

客户要求ASP.NET Core API返回特定格式,怎么办?(续)

ASP.NET Core API 在从 React 客户端调用时返回 401

使用ETag协议实现ASP.NET Core API缓存

Blazor ASP.Net Core 3.1 Web API 在发布时返回 404 错误

ASP.NET Core Refit Client for RESTful API:如何划分客户端

ASP.NET Core MVC 使用 api +javascript 客户端与 ajax