.NET宝藏API之:OutputFormatter,格式化输出对象
相信大家在项目中都用过统一响应参数模板。
先声明一个响应模板类:
public class ResponseDto
{
public int code { get; set; }
public string msg { get; set; }
public object data { get; set; }
}
再定义返回成功和失败的方法:
public IActionResult Success(object data)
{
return ......
}
public IActionResult Fail(string msg)
{
return ......
}
在接口返回时统一调用:
[HttpGet]
public IActionResult Get()
{
var data = new WeatherForecast() { Date = DateTime.Now };
return Success(data);
}
当然了,这篇文章所讲的OutputFormatter
和上面的统一模板不冲突哈,存在共通之处,都是格式化响应参数嘛,拿来做个引子。
OutputFormatter
OutputFormatter
是所有格式化输出的基类,有唯一的子类:TextOutputFormatter
,同时TextOutputFormatter
又有一大堆子类:
JsonOutputFormatter
NewtonsoftJsonOutputFormatter
StringOutputFormatter
SystemTextJsonOutputFormatter
XmlDataContractSerializerOutputFormatter
XmlSerializerOutputFormatter
如果不配置任何响应参数输出格式,asp.net core api
响应参数默认的输出格式就是json
。
猴:这个接口给我返回xml
,我不要json
。
我:你是不是脑子有毛病?好好的json
不用用xml
。
得,前端大佬得要求还是得满足不是,这时候有些同学是不是已经去百度:.Net怎么将对象转换成xml?
No
No
No
,这时候就轮到OutputFormatter
的孙子 XmlDataContractSerializerOutputFormatter
出场了。
只需要简单给接口配置一个属性就搞定啦。
[Produces("application/xml")]
[HttpGet]
public WeatherForecast Get()
{
return new WeatherForecast() { Date = DateTime.Now };
}
我们来运行看一看:
wtf
,怎么会406
。
406:表示客户端无法解析服务端返回的内容。说白了就是后台的返回结果前台无法解析就报406错误。
哦,原来是忘了在Startup
中配置我们的孙子XmlDataContractSerializerOutputFormatter
。
services.AddControllers((c) =>
{
c.OutputFormatters.Add(new XmlDataContractSerializerOutputFormatter());
});
注意:不只是没有在Startup
中会出现406
哦,以下情况也会出现:
- contentType不存在
- contentType与响应参数不匹配
OutputFormatter扩展
上面介绍了内置OutputFormatter
的使用,那如果我们想自定义呢?当然也是可以的。
下面我们就用自定义的OutputFormatter
实现顶部响应模板的效果:
public class ObjectOutputFormatter : TextOutputFormatter
{
public ObjectOutputFormatter()
{
SupportedEncodings.Add(Encoding.UTF8);
SupportedEncodings.Add(Encoding.Unicode);
// 这就是我们自定义contentType的名称
SupportedMediaTypes.Add("text/object");
}
public override async Task WriteResponseBodyAsync(OutputFormatterWriteContext context, Encoding selectedEncoding)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
if (selectedEncoding == null)
{
throw new ArgumentNullException(nameof(selectedEncoding));
}
string text = JsonConvert.SerializeObject(new ResponseDto()
{
msg = "成功,自定义的哦",
code = 200,
data = context.Object
});
var response = context.HttpContext.Response;
await response.WriteAsync(text, selectedEncoding);
}
}
[Produces("text/object")]
[HttpGet]
public WeatherForecast Get()
{
return new WeatherForecast() { Date = DateTime.Now };
}
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers((c) =>
{
c.OutputFormatters.Add(new XmlDataContractSerializerOutputFormatter());
// 我们自定义的输出格式
c.OutputFormatters.Add(new ObjectOutputFormatter());
});
}
搞定,我们来看看效果:
ActionFilterAttribute
有些同学可能会想到过滤器,是的,上面的效果过滤器也能实现:
public class ResultFilter : ActionFilterAttribute
{
public override void OnResultExecuting(ResultExecutingContext context)
{
ResponseDto result = new ResponseDto();
result.code = 200;
result.msg = "成功,ResultFilter";
var properties = context.Result.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public);
result.data = properties.FirstOrDefault(c => c.Name == "Value").GetValue(context.Result);
context.Result = new JsonResult(result);
base.OnResultExecuting(context);
}
}
[TypeFilter(typeof(ResultFilter))]
[HttpGet]
public WeatherForecast Get()
{
return new WeatherForecast() { Date = DateTime.Now };
}
猴:有了过滤器为什么还搞个OutputFormatter
呢?
我:不能因为过滤器可以实现同样的功能就认为OutputFormatter
多余了,很显然过滤器的操作对象是请求/响应上下文,而OutputFormatter
的操作对象则是响应参数。再说了,ActionFilterAttribute
过滤器只是众多过滤器的一种。
猴:那过滤器和自定义OutputFormatter
一起用会是什么效果呢?是不是像下面这样?
我:不是,过滤器和自定义OutputFormatter
同时使用,生效的只有过滤器,不信可以打断点试一下哦。
[Produces("text/object")]
[TypeFilter(typeof(ResultFilter))]
[HttpGet]
public WeatherForecast Get()
{
return new WeatherForecast() { Date = DateTime.Now };
}
具体原因在这里就不细说了,等后面再分享(其实我也还没弄清楚,逼着自己去了解)
好了,这期的宝藏API
就到这了,下期再见哦,如果有下期的话。
.NET宝藏API之:OutputFormatter,格式化输出对象的更多相关文章
- JAXP使用Stax API时格式化输出XML
最近项目中需要生成XBRL instance,对于XML读写和验证进行了一些学习.由于Stax API不支持格式化输出,默认全都写在一行上,网上也没有搜到现成的东西,自己写了一个格式化输出的帮助类. ...
- Python自动化运维之4、格式化输出、文件对象
Python格式化输出: Python的字符串格式化有两种方式: 百分号方式.format方式 百分号的方式相对来说比较老,而format方式则是比较先进的方式,企图替换古老的方式,目前两者并存.[P ...
- 格式化输出Json对象
1.调用方式: alert(JsonUti.convertToString(jsonObj)); //jsonObj为json对象. 2.格式化输出Json对象方法定义: var JsonUti = ...
- kubectl格式化输出和调试
1.格式化输出 以特定的格式想终端输出详细信息,可以在 kubectl 命令中添加 -o 或者 -output 选项 输出格式 描述 -o=custom-columns=<spec> 使 ...
- 使用BigDecimal进行精确运算以及格式化输出数字
一.引言 借用<Effactive Java>这本书中的话,float和double类型的主要设计目标是为了科学计算和工程计算.他们执行二进制浮点运算,这是为了在广域数值范围上提供 ...
- (Python )格式化输出、文件操作、json
本节学习Python的格式化输出,文件操作以及json的简单用法 1.格式化输出 将非字符串类型转换成字符串,可以使用函数:str() 或者repr() ,(这两个函数的区别目前我还没搞懂,求解答) ...
- XStream、JAXB 日期(Date)、数字(Number)格式化输出xml
XStream.Jaxb是java中用于对象xml序列化/反序列化 的经典开源项目,利用它们将对象转换成xml时,经常会遇到日期(Date).数字按指定格式输出的需求,下面是使用示例: 一.日期字段格 ...
- python字符串格式化输出
python格式化输出 python格式化输出有两种方式:百分号和format format的功能要比百分号方式强大,其中format独有的可以自定义字符填充空白.字符串居中显示.转换二进制.整数自动 ...
- python基础之常用模块以及格式化输出
模块简介 模块,用一砣代码实现了某个功能的代码集合. 类似于函数式编程和面向过程编程,函数式编程则完成一个功能,其他代码用来调用即可,提供了代码的重用性和代码间的耦合.而对于一个复杂的功能来,可能需要 ...
随机推荐
- K-good number Theory + 数学问题
这道题是我做CodeTon Round1时的D题,总的来看思路很重要,有几个比较明显的切入问题的角度,要选择到最优的那个: 先看题目: 我们可以发现,这道题的描述一目了然,就是说我们能不能找k个数的和 ...
- Java 实现汇总排序
排序在系统中经常能用到,一般可以在数据库做排序,也可以在服务端做排序.在数据库一般使用 order by 排序.而服务端也是使用快排.本期使用汇总排序. 问题 统计销售数据,每个销售员都有对应的部门和 ...
- Java注释相关以及IDEA配置相关的注释
本文章主要包括以下6个内容: 一.注释分类以及javadoc的使用 二.使用Alibaba Java Coding Guidelines规范编码. 三.IDEA配置类注释 四.IDEA配置方法注释 = ...
- 团队vue基础镜像选择思考
前端镜像可以考虑使用nginx或者openresty; 镜像 大小 说明 nginx:1.20.2-alpine 8.41 MB 最小最新版本 nginx:1.21.4 50.95 MB 最新版本 n ...
- Ls 命令执行什么功能? 可以带哪些参数,有什么区别?
ls 执行的功能: 列出指定目录中的目录,以及文件哪些参数以及区别: a 所有文件 l 详细信息,包括大小字节数,可读可写可执行的权限等
- 可以直接调用 Thread 类的 run ()方法么?
当然可以.但是如果我们调用了 Thread 的 run()方法,它的行为就会和普通的方 法一样,会在当前线程中执行.为了在新的线程中执行我们的代码,必须使用 Thread.start()方法.
- idea中Git的配置和Github上推拉项目
1.去官网下载Git,并且安装它.安装步骤较为简单,此处就不再赘述. 2.在idea中配置Git信息 Git路径就是你电脑中安装Git的位置,找到git.exe文件(正常情况下,idea都会自动给你匹 ...
- scanf()函数的原理
最近使用scanf发现了自己对scanf函数还是不太了解,主要出现在无意中出现的一个错误: scanf正确的写法是,scanf中以什么格式输入变量,则变量的类型就应该是什么格式,如下面scanf输入到 ...
- mian中的argv调用时为什么不是*argv
c++main函数char * argv[]是个指针数组,元素是指针,为何argv[1]得到不是地址? 照我的理解char *argv[]保存的应该是一组指针,即地址,每个地址中保存的是char类型变 ...
- 关于css布局、居中的问题以及一些小技巧
CSS的两种经典布局 左右布局 一栏定宽,一栏自适应 <!-- html --> <div class="left">定宽</div> < ...