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

前言

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

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

怎么办?

思路

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

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

13f262f3c298d493c2dc27e2e3f65c3d.png

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

DefaultOutputFormatterSelector

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

219a21a26a76e84acf36d190bbe9f870.png

其中,选择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派生的类型或返回特定类型:

c3b8014ea70c629bcbc209eec39259a7.png

那么实现目标就转化为,将返回类型设为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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/292738.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

第四章例题、心得及问题。

例题4-1&#xff1a; #include<stdio.h> #include<math.h> int main(void) {int denominator,flag;double item,pi;flag1;denominator1;item1.0;pi0;while(fabs(item)>0.0001){itemflag*1.0/denominator;pipiitem;flag-flag;denominatordenominator2;}pipi*4;pr…

springboot springcloud区别_SpringCloud微服务全家桶-第一篇!为什么要用微服务

从今天开始&#xff0c;学习SpringCloud微服务全家桶。一、引导1、什么是微服务&#xff1f;2、微服务之间是如何独立通讯的3、springCloud和Dubbo有哪些区别&#xff1f;4、什么是服务熔断&#xff1f;什么是服务降级5、微服务的优缺点分别是什么&#xff1f;6、微服务技术栈有…

C#之Lock

lock 关键字将语句块标记为临界区&#xff0c;方法是获取给定对象的互斥锁&#xff0c;执行语句&#xff0c;然后释放该锁。 class Program{static void Main(string[] args){Thread t new Thread(LockObject.MonitorIncrement);Thread t1new Thread(new ThreadStart(LockObje…

记一次 .NET 某消防物联网 后台服务 内存泄漏分析

一&#xff1a;背景 1. 讲故事去年十月份有位朋友从微信找到我&#xff0c;说他的程序内存要炸掉了。。。截图如下&#xff1a;时间有点久&#xff0c;图片都被清理了&#xff0c;不过有点讽刺的是&#xff0c;自己的程序本身就是做监控的&#xff0c;结果自己出了问题&#xf…

高性能网站建设的最佳实践(二)

原文译自雅虎开发者社区&#xff0c;转载译文请标明出处。关注我的sina微博&#xff0c;共同进步&#xff01;为了让网页响应速度更快Exceptional Performance团队列出了一系列的最佳实践&#xff0c;包括35个最佳实践条目&#xff0c;分成7种类型类。避免重定向标签&#xff1…

python带通配符的字符串匹配_Bash技巧:实例介绍数个参数扩展表达式以处理字符串变量...

Linux 的 bash shell 提供了多种形式的参数扩展表达式&#xff0c;可以获取变量自身的值&#xff0c;或者对变量值进行特定处理得到一个新的值&#xff0c;等等。本篇文章对字符串变量值相关的参数扩展表达式进行汇总说明。假设在 bash 中定义了 filepathexample/subdir/testfi…

幸福手机,给爸妈的高端大气上档次的手机

打造高端老人手机——幸福手机 江苏智联天地科技有限公司历经2年&#xff0c;手机研发投入超过4000万&#xff0c;打造中国第一品牌的高端老人手机&#xff0c;手机将于2014年12月正式对外发布&#xff0c;是国内第一款高端老人手机——幸福手机&#xff08;ThimFone&#xff0…

MASA Framework - EventBus设计

概述利用发布订阅模式来解耦不同架构层级&#xff0c;亦可用于解决隔离业务之间的交互优点&#xff1a;松耦合横切关注点可测试性事件驱动发布订阅模式发布者通过调度中心将消息发送给订阅者。调度中心解决发布与订阅者之间的关系&#xff0c;保证消息可以送达订阅者手中。发布…

wireshark-win64-3.4.0安装_这9类轴承的安装方法,你可都知道?有哪些需要注意的呢?...

轴承是当代机械设备中一种重要零部件。随着时间的推移&#xff0c;轴承会发生磨损&#xff0c;合理的安装和使用可以让机械设备减少不必要的安全隐患。前面文章讲了如何拆卸轴承&#xff0c;今天就给大家讲讲各类轴承应该如何安装&#xff01;一、轴承安装前的准备工作轴承的安…

史上最牛数学简史

全世界只有3.14 % 的人关注了爆炸吧知识“中国现代数学之父”华罗庚曾说过宇宙之大&#xff0c;粒子之微火箭之速&#xff0c;化工之巧地球之变&#xff0c;生物之谜日用之繁&#xff0c;无处不用数学回首往昔数学始终伴随我们左右纵横交错的几何、繁琐复杂的运算难以求解的方程…

linux下使用pidcat找bug

第一步&#xff1a; 安装pidcat 第二步&#xff1a; 找到APP的包名比如adb shell ps | grep sangforadb shell pm list package第三步&#xff1a; 在ubuntu终端输入pidcat.py 包名结果&#xff1a;

创建与删除索引

索引是加速查询的主要手段&#xff0c;特别对于涉及多个表的查询更是如此。本节中&#xff0c;将介绍索引的作用、特点&#xff0c;以及创建和删除索引的语法。13.4.1 使用索引优化查询索引是高速定位数据的技术&#xff0c;首先通过一个演示样例来了解其含义及作用&#xff0…

r vector 4 elements_Vector类与Enumeration接口

Vector类用于保存一组对象&#xff0c;由于java不支持动态数组&#xff0c;Vector可以用于实现跟动态数组差不多的功能。如果要将一组对象存放在某种数据结构中&#xff0c;但是不能确定对象的个数时&#xff0c;Vector是一个不错的选择。例&#xff1a;将键盘上输入的一个数字…

[深入JUnit] 测试运行的入口

阅读前提 了解JUnit 对JUnit的内部实现有兴趣 不妨看看[深入JUnit] Before, After, Test的秘密] 代码版本: junit 4.12代码搜索工具&#xff1a; http://grepcode.com/常用符号 _: 用来略去代码段中无关紧要的parameter ...: 用来略去无关紧要的代码实现 本文的展开方式&…

.NET6之MiniAPI(七):中间件

http协议&#xff0c;是由客户端发出请求&#xff0c;服务端响应结果并返回&#xff0c;我们把这个请求来回抽象成一个请求管道&#xff0c;那中间件就是这个管道上的阀门&#xff0c;控制着流量的进出和中断。每一个请求都要经过中间件的过滤&#xff0c;滤掉不合格的请求&…

linux之telnet命令使用

telnet命令通常用来远程登录。telnet程序是基于TELNET协议的远程登录客户端程序。Telnet协议是TCP/IP协议族中的一员&#xff0c;是Internet远程登陆服务的标准协议和主要方式。它为用户提供了在本地计算机上完成远程主机工作的 能力。在终端使用者的电脑上使用telnet程序&…

arraylist从大到小排序_经典排序方法的python实现和复杂度分析

1.冒泡排序:冒泡排序算法的运作如下&#xff1a;比较相邻的元素。如果第一个比第二个大(升序)&#xff0c;就交换他们两个。对每一对相邻元素作同样的工作&#xff0c;从开始第一对到结尾的最后一对。这步做完后&#xff0c;最后的元素会是最大的数。针对所有的元素重复以上的步…