百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 热门文章 > 正文

NET宝藏API之:OutputFormatter,格式化输出对象

bigegpt 2024-08-07 17:47 2 浏览

相信大家在项目中都用过统一响应参数模板。

先声明一个响应模板类:

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,格式化输出对象 - 畅饮无绪 - 博客园

相关推荐

VS Code上也能玩转Jupyter Notebook,这是一份完整教程

点击上方"码农真经"关注,星标或者置顶22点24分准时推送,第一时间送达来源:公众号机器之心|编辑:真经君码农真经(ID:coder_experience)第115次推文图源:...

看开发一款AR眼镜产品都需要那些东东?

开发AR眼镜应用时,使用的操作系统和编程语言主要取决于目标设备和开发平台。以下是主流AR眼镜的开发系统和语言总结:一、操作系统WindowsHolographic设备:微软HoloLens系列特点:...

ONNX Runtime 黑科技曝光:一行 C++ 代码让 ResNet 起飞,GitHub 已爆星

1.ONNXRuntime简介ONNXRuntime(ORT)是由微软开发的高性能推理引擎,支持跨平台(Windows/Linux/macOS)运行ONNX格式的深度学习模型。其核心优势...

海康工业相机SDK开发介绍

这篇文章,我来介绍一下海康工业相机SDK的使用方法。如果是老手,你可以跳过,如果是新手,可以看看,欢迎拍砖要使用海康的工业相机SDK,要先下载机器视觉工业相机SDKV3.2.0版本Runtime组...

深圳机器视觉相机USB3.0数字相机及千兆网口相机有什么特点?

四元数机器视觉相机的目的是将通过镜头投影到传感器的图像传送到能够储存、分析和(或者)显示的机器设备上。那么深圳机器视觉相机USB3.0数字相机及千兆网口相机有什么特点?相信不少人是有疑问的,今天深圳四...

蚁利智慧工地展厅控制系统:多媒体交互软件及中控系统开发方案

来源:蚁利科技以下是一篇关于隆兰智慧工地安全体验数字展厅多媒体互动软件及中控系统开发技术的技术方案框架,包含核心代码示例和实现思路:---#隆兰智慧工地安全体验数字展厅开发技术方案##一、系统架构...

C#程序员在工控行业到底有没有立足之地

当年忐忑的从互联网卷到工控圈时也一脸懵逼,结果发现咱C#程序员在工控界简直是万金油!今天就用我踩坑几年的经验给你们盘一盘转行路线。一、能撸哪些岗位?上位机开发工程师(工控圈入场券):天天和PLC、传感...

C#一行代码搞定OCR

本文将介绍如何使用C#代码来实现OCR功能。一、在VS中新建一个控制台应用,选择.net框架,.net6.0~8.0均可。创建好的项目如下图,然后在配置管理器中修改活动解决方案平台为x64,以及项目平...

在 C# WinForms 中 OpenCvSharp 进行边缘检测:Laplacian 算子介绍

边缘检测在计算机视觉和图像处理领域中具有非常重要的作用,它是物体识别、特征提取的基础。Laplacian算子是一种经典且常用的边缘检测方法,它对噪声非常敏感,能够很好地检测到图像中的细节和边缘。本文...

C# OpenCV机器视觉:对位贴合

在热闹非凡的手机维修街上,阿强开了一家小小的手机贴膜店。每天看着顾客们自己贴膜贴得歪歪扭扭,不是膜的边缘贴不整齐,就是里面充满了气泡,阿强心里就想:“要是我能有个自动贴膜的神器,那该多好啊,就可以让顾...

C# OpenCV机器视觉:缺陷检测

在一个阳光明媚的早晨,阿强正准备享受他的一杯咖啡,突然接到了老板的电话。“阿强,我们的生产线出现了问题!有几个产品的质量不合格,客户投诉不断!你能不能想办法解决这个问题?”阿强一听,心中一紧,随即灵光...

CHAPTER II 第二章

CHAPTERIICHAPTERII第二章Iresistedalltheway:anewthingforme...

万字图文,将"类加载器"与"双亲委派机制"一网打尽

引子大家想必都有过平时开发springboot项目的时候稍微改动一点代码,就得重启,就很烦网上一般介绍2种方式spring-boot-devtools,或者通过JRebel插件来实现"...

Java:Java中的微服务

  如果你想使用Java中的云原生微服务快速实现大规模可扩展性,那么不需要重新发明轮子。一些创新工具可以帮助你。通过Java培训课程,在Java(软件开发中最常用的编程语言)方面打下坚实的基础,更好地...

"类加载器"与"双亲委派机制"一网打尽

引子大家好,我是呼噜噜,大家想必都有过平时开发springboot项目的时候稍微改动一点代码,就得重启,就很烦网上一般介绍2种方式spring-boot-devtools,或者通过JRebel插件...