.NET Core 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 };
}

到此这篇关于.NET Core API之格式化输出对象OutputFormatter的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • .Net Core解决WebAPI中返回时间格式带T的问题

    在项目开发中遇到了返回的时间格式带T的问题,如图所示: 直接把这种结果返回给前端,前端很难处理这个时间格式问题,所以就需要后端在返回数据的时候对这种格式进行处理. 新建Order类: using System; namespace WebApiTest { public class Order { public int ID { get; set; } public DateTime OrderTime { get; set; } } } 新建一个格式化类DatetimeJsonConverte

  • ASP.NET Core在WebApi项目中使用MiniProfiler分析Entity Framework Core

    安装配置MiniProfiler 在现有的ASP.NET Core MVC WebApi 项目里,通过Nuget安装MiniProfiler: Install-Package MiniProfiler.AspNetCore.Mvc MiniProfiler.EntityFrameworkCore 当然也可以通过Nuget Package Manager可视化工具安装 接下来就是如何配置和使用 MiniProfiler 了,总共分三步: 第一步,来到Startup.cs的ConfigureServ

  • .Net Core 3.1 Web API基础知识详解(收藏)

    目录 一.前言 二.Swagger调试Web API 三.配置文件 四.文件上传 五.统一WebApi数据返回格式 六.模型验证 七.日志使用 八.依赖注入 九.缓存 十.异常处理 十一.应用安全与JWT认证 十二.跨域 一.前言 随着近几年前后端分离.微服务等模式的兴起,.Net Core也似有如火如荼之势 ,自16年发布第一个版本到19年底的3.1 LTS版本,以及将发布的.NET 5,.NET Core一路更迭,在部署和开发工具上也都支持了跨平台应用.一直对.Net Core有所关注,但未

  • ASP.NET Core WebApi返回结果统一包装实践记录

    目录 前言 统一结果类封装 定义包装类 升级一下操作 进一步完善 漏网之鱼处理 总结 前言 近期在重新搭建一套基于ASP.NET Core WebAPI的框架,这其中确实带来了不少的收获,毕竟当你想搭建一套框架的时候,你总会不自觉的去想,如何让这套框架变得更完善一点更好用一点.其中在关于WebApi统一结果返回的时候,让我也有了更一步的思考,首先是如何能更好的限制返回统一的格式,其次是关于结果的包装一定是更简单更强大.在不断的思考和完善中,终于有了初步的成果,便分享出来,学无止境思考便无止境,希

  • ASP.NET Core使用Swagger/OpenAPI规范

    目录 1.什么是Swagger/OpenAPI? 2.NET Swagger实现 3.Swashbuckle主要组成部分 4.什么是REST? 5.配置Swagger中间件 6.XML注释 7.数据注释 1.什么是Swagger/OpenAPI? Swagger是一个与语言无关的规范,用于描述REST API.因为Swagger项目已捐赠给OpenAPI计划,所以也叫OpenAPI.它允许计算机和人员了解服务的功能,可以直接在线访问测试API方法.而Swagger UI提供了基于Web的UI,它

  • ASP.NET Core在WebApi项目中使用Cookie

    目录 一.Cookie的作用 二.在ASP.NET Core中使用Cookie 1.在控制器中直接使用Cookie 1.1.设置Cookie 1.2.获取Cookie 1.3.删除Cookie信息 2.封装Cookie 一.Cookie的作用 Cookie通常用来存储有关用户信息的一条数据,可以用来标识登录用户,Cookie存储在客户端的浏览器上.在大多数浏览器中,每个Cookie都存储为一个小文件.Cookie表示为键/值对的形式,可以利用键来读取.写入或删除Cookie. 在ASP.NET

  • ASP.NET Core之Web API介绍

    目录 1.简单介绍 2.自定义格式化(Format) 1.特定格式的操作结果 2.配置格式化程序 3.添加对 XML 格式的支持 4.强制特定格式化 5.响应格式 URL 映射 6.自定义格式化程序 Protocol Buffers (简称 protobuf) 1.简单介绍 ASP.NET Core Web API 是 ASP.NET Core MVC 的一个功能.ASP.NET Core MVC 包含了对 Web API 的支持.可以构建多种客户端的 HTTP 服务.ASP.NET Core

  • .NetCore Web Api 利用ActionFilterAttribute统一接口返回值格式及问题解析

    .Net Core 同 Asp.Net MVC一样有几种过滤器,这里不再赘述每个过滤器的执行顺序与作用. 在实际项目开发过程中,统一API返回值格式对前端或第三方调用将是非常必要的,在.NetCore中我们可以通过ActionFilterAttribute来进行统一返回值的封装. 在封装之前我们需要考虑下面几个问题: 1,需要对哪些结果进行封装 我目前的做法是,只对ObjectResult进行封装,其他的类型:FileResult,ContentResult,EmptyResult,Redire

  • .Net Core创建Api进行文件上传功能

    1.Net Core创建api接口,用于接收外部请求,进行文件的上传 2.添加控制器类,添加如下代码: [HttpPost] [Route("PostFile")] public String PostFile([FromForm] IFormCollection formCollection) { String result = "Fail"; if (formCollection.ContainsKey("user")) { var user

  • .Net Core3.0 WebApi 项目框架搭建之使用Serilog替换掉Log4j

    为什么使用Serilog Serilog 是一个用于.NET应用程序的日志记录开源库,配置简单,接口干净,并可运行在最新的.NET平台上,与其他日志库不同, Serilog 是以功能强大的结构化事件数据为基础构建的, 支持将日志输出到控制台.文件.数据库和其它更多的方式,支持参数化日志模板,非常灵活. 之前我们项目使用的是Log4j来记录用户日志的,在开发的过程中,慢慢的发现Log4j好像并不能满足我们的需求,比如结构化,日志分析等,于是决定使用serilog来替换掉Log4j,在使用的过程中发

随机推荐