介绍

Web API为JSON和XML提供媒体类型格式化程序。框架默认将这些格式化程序插入管道中。客户端可以在HTTP请求的Accept标头中请求JSON或XML.

格式化数据这个东西,其实没有什么最好的数据,要看各种场景,最适合才是最好的,不是说json就比xml好,容易解析什么的等。

废话不多说了,概念的东西大家一百度一大堆。开始我们的正文吧,当然首先我们还是要创建一个WebAPI项目,不会创建请返回第一章:如何创建简单的WebAPI项目

控制器的返回类型

特定类型:

首先我们最熟悉的就是特定类型了,比如stting或自定义对象类型等。就例如模版控制器的就是返回一个字符串数组类型:

     [HttpGet]
public ActionResult<IEnumerable<string>> Get()
{
return new string[] { "value1", "value2" };
}

这种的示例没有已知条件,直接返回特定类型即可了 ,但是有些操作我们需要考虑已知的条件,这时候会返回多个返回结果。根据不同的条件返回对应结果,下面我们来看一下IActionResult 类型。

IActionResult 类型:

在多种情况条件返回多个不同结果时, 要支持此类操作,必须使用 IActionResult 或 ActionResult<T>。ActionResult类型表示多种的HTTP状态码。属于此类别的一些常见返回类型包括:

BadRequestResult (400)

NotFoundResult (404)

OkObjectResult (200)

在返回多个类型的时候我们如何返回不同的类型哪,我们可以借助【ProducesResponseType】特性来帮助我们实现返回自定义多个类型。下面我们写个简单的get方法的同步和异步的示例:

同步示例:

返回两个情况当id为5我给你正确返回,不是5我就找不到。当然实际情况肯定不是这个样子,但是就是打一个找资源的例子,找到就返回,找不到就返回404,。

 [HttpGet("{id}")]
[ProducesResponseType(, Type = typeof(Person))]
[ProducesResponseType()]
public IActionResult Get(int id)
{
if (id == )
{
return Ok(new Person
{
Id = "",
name = "姓名1",
age = ,
Birthday = DateTime.Now,
introduce = "介绍001"
});
}
else
{
return NotFound();
} }

下面是异步的方法:

 [HttpGet("{id}")]
[ProducesResponseType(, Type = typeof(Person))]
[ProducesResponseType()]
public async Task<IActionResult> Get(int id)
{
if (id == )
{ await Task.Run(()=>System.Threading.Thread.Sleep());
return Ok(new Person
{
Id = "",
name = "姓名1",
age = ,
Birthday = DateTime.Now,
introduce = "介绍001"
});
}
else
{
return BadRequest();
} }

CreatedAtAction方法:创建一个CreatedAtActionResult对象,该对象生成Status201Created响应;具体想要了解的可以查看官方文档:CreatedAtAction方法介绍

下面我们看一下请求结果:

id不是5的时候返回找不到:

id为5的时候正常返回咱们的对象:

ActionResult<T> 类型:

这个类型是从ASP.NET Core 2.1引入的,所有使用前请看下版本哦。它支持返回从 ActionResult 派生的类型或返回特定类型。 ActionResult<T> 通过 IActionResult 类型可提供以下优势:

  • 可排除 [ProducesResponseType] 特性的 Type 属性
  • 隐式强制转换运算符支持将 T 和 ActionResult 均转换为 ActionResult<T>。 将 T 转换为 ObjectResult,也就是将 return new ObjectResult(T); 简化为 return T,什么个意思哪,说白了就是在定义的时候指定了类型直接return就可以了。

返回响应补充:

  • OK:创建一个OkResult对象,该对象生成一个空的Status200OK响应。
  • NoContentResult:没有内容,为响应创建的NoContentResult对象
  • NotFound():没有找到,为响应创建的NotFoundResult。

  • PhysicalFile(string【文件的路径】,string【内容类型】):返回由physicalPath(Status200OK)指定的文件。

  • Redirect(string【url】):重定向,为响应创建的RedirectResult。
  • StatusCode(int【返回的状态码】,object【值】):自定义返回状态,切附带返回值。其实是为响应创建了ObjectResult对象。

我就写部分常用的其他的有兴趣可以去官网了解一下:返回状态相应

自定义格式化程序

我们都知道WebAPI因为MVC的内置所以默认支持了json,xml和文本格式。那么我们想使用其他格式怎么办哪,微软总是不会让我们失望,我们可以自定义啊。

首先创建自定义格式化程序大致步骤:

  • 从相应的基类中派生类。
  • 在构造函数中指定有效的媒体类型和编码。
  • 重写 CanReadType/CanWriteType 方法
  • 重写 ReadRequestBodyAsync/WriteResponseBodyAsync 方法

从相应的基类中派生:

从那些类中派生官方给的解释是;

对于文本媒体类型(例如,vCard),从 TextInputFormatter 或 TextOutputFormatter 基类派生。

对于二进制类型,从 InputFormatter 或 OutputFormatter 基类派生。

例如官方示例:

public class VcardOutputFormatter : TextOutputFormatter

指定有效的媒体类型和编码

在构造函数中,通过添加到 SupportedMediaTypes 和 SupportedEncodings 集合来指定有效的媒体类型和编码。

public VcardOutputFormatter()
{
SupportedMediaTypes.Add(MediaTypeHeaderValue.Parse("text/vcard")); SupportedEncodings.Add(Encoding.UTF8);
SupportedEncodings.Add(Encoding.Unicode);
}

重写 CanReadType/CanWriteType

通过重写 CanReadType 或 CanWriteType 方法,指定可反序列化为或从其序列化的类型。 例如,可能只能从 Contact 类型创建 vCard 文本,反之亦然。

protected override bool CanWriteType(Type type)
{
if (typeof(Contact).IsAssignableFrom(type)
|| typeof(IEnumerable<Contact>).IsAssignableFrom(type))
{
return base.CanWriteType(type);
}
return false;
}

CanWriteResult方法不一定必须重写,但是有时候确实必须的,必须重写官方给的解释是;

  • 操作方法返回模型类。
  • 具有可能在运行时返回的派生类。
  • 需要知道操作在运行时返回了哪个派生类。

简单的意思是如果你返回的类型是父类的话,但是实际返回值可能存在子类型的返回且子类型为多个。但是你仅仅希望处理其中一个子类型的返回。这个时候可以使用CanWriteResult提供的上下文来检查对象类型。

重写 ReadRequestBodyAsync/WriteResponseBodyAsync

实际的反序列化或序列化工作在 ReadRequestBodyAsync 或 WriteResponseBodyAsync 中执行。 以下示例中突出显示的行展示了如何从依赖关系注入容器中获取服务(不能从构造函数参数中获取它们)

public override Task WriteResponseBodyAsync(OutputFormatterWriteContext context, Encoding selectedEncoding)
{
IServiceProvider serviceProvider = context.HttpContext.RequestServices;
var logger = serviceProvider.GetService(typeof(ILogger<VcardOutputFormatter>)) as ILogger; var response = context.HttpContext.Response; var buffer = new StringBuilder();
if (context.Object is IEnumerable<Contact>)
{
foreach (Contact contact in context.Object as IEnumerable<Contact>)
{
FormatVcard(buffer, contact, logger);
}
}
else
{
var contact = context.Object as Contact;
FormatVcard(buffer, contact, logger);
}
return response.WriteAsync(buffer.ToString());
}
private static void FormatVcard(StringBuilder buffer, Contact contact, ILogger logger)
{
buffer.AppendLine("BEGIN:VCARD");
buffer.AppendLine("VERSION:2.1");
buffer.AppendFormat($"N:{contact.LastName};{contact.FirstName}\r\n");
buffer.AppendFormat($"FN:{contact.FirstName} {contact.LastName}\r\n");
buffer.AppendFormat($"UID:{contact.ID}\r\n");
buffer.AppendLine("END:VCARD");
logger.LogInformation($"Writing {contact.FirstName} {contact.LastName}");
}

官方示例DOME下载

传送门

WebApi系列文章目录介绍

【WebAPI No.5】Core WebAPI中的自定义格式化的更多相关文章

  1. Asp.net Core WebApi 使用Swagger做帮助文档,并且自定义Swagger的UI

    WebApi写好之后,在线帮助文档以及能够在线调试的工具是专业化的表现,而Swagger毫无疑问是做Docs的最佳工具,自动生成每个Controller的接口说明,自动将参数解析成json,并且能够在 ...

  2. ASP.NET Core WebAPI中的分析工具MiniProfiler

    介绍 作为一个开发人员,你知道如何分析自己开发的Api性能么? 在Visual Studio和Azure中, 我们可以使用Application Insight来监控项目.除此之外我们还可以使用一个免 ...

  3. .NET Core WebApi中实现多态数据绑定

    什么是多态数据绑定? 我们都知道在ASP.NET Core WebApi中数据绑定机制(Data Binding)负责绑定请求参数, 通常情况下大部分的数据绑定都能在默认的数据绑定器(Binder)中 ...

  4. ASP.NET Core WebApi 返回统一格式参数(Json 中 Null 替换为空字符串)

    相关博文:ASP.NET Core WebApi 返回统一格式参数 业务场景: 统一返回格式参数中,如果包含 Null 值,调用方会不太好处理,需要替换为空字符串,示例: { "respon ...

  5. Asp.Net Core WebApi中接入Swagger组件(初级)

    开发WebApi时通常需要为调用我们Api的客户端提供说明文档.Swagger便是为此而存在的,能够提供在线调用.调试的功能和API文档界面. 环境介绍:Asp.Net Core WebApi + S ...

  6. 如何在启用JWT Token授权的.NET Core WebApi项目中下载文件

    背景 前几天,做项目的时候遇到一个文件下载的问题.当前系统是一个前后端分离的项目,前端是一个AngularJs项目, 后端是一个.NET Core WebApi项目.后端的Api项目使用了Jwt To ...

  7. Asp.Net Core WebAPI+PostgreSQL部署在Docker中

     PostgreSQL是一个功能强大的开源数据库系统.它支持了大多数的SQL:2008标准的数据类型,包括整型.数值值.布尔型.字节型.字符型.日期型.时间间隔型和时间型,它也支持存储二进制的大对像, ...

  8. 如何将dotnet core webapi发布到docker中…

    如何将dotnet core webapi发布到docker中 今天想起来撸一下docker,中途还是遇到些问题,但是这些问题都是由于路径什么的导致不正确,在这儿还是记录下操作过程,今天是基于wind ...

  9. 关于修改.net core webapi中null默认返回的状态码。

    在asp .net core webapi中,http请求的响应数据如果是null的话,我们知道状态码会返回204,即NoContent,为什么会出现这种情况呢?   因为在返回响应数据的时候,nul ...

随机推荐

  1. 545. Boundary of Binary Tree二叉树的边界

    [抄题]: Given a binary tree, return the values of its boundary in anti-clockwise direction starting fr ...

  2. flex布局实现elment容器布局

    一.flex布局是什么 flex布局,意为"弹性布局",是一种响应式的布局方法 采用 Flex 布局的元素,称为 Flex 容器,它的所有子元素自动成为容器成员. 先放上一个ele ...

  3. js、jquery、jsp的区别

    1.JSP全称是java server page    JS全称是javaScript 2.最主要的区别是运行位置不同. JSP运行在后台服务器上,混合在HTML中的java程序段用于控制HTML的动 ...

  4. 23. pt-slave-delay

    略过,用原生的延迟复制: stop slave; change master to master_delay=5; start slave;

  5. MD5加密算法的Java版本

    网上搜索Java实现MD5的资料很多,错误的也很多. 之前编写的一个阿里云直播鉴权原理算法需要用到MD5算法,网上找了几个,都是不行,浪费了时间,现在贴一个,做备用. import java.secu ...

  6. PB的一些记录

    断点设置在函数内,发现返回值没有,需要取消函数内断点才正常 加密--采用矩阵乘法 行列式取+_1的矩阵与逆矩阵其元素都是整数,, 可以使用matlab来找到这些矩阵 A* I   =E       A ...

  7. springboot读取properties和yml配置文件

    一.新建maven工程:springboot-configfile-demo,完整工程如下: pom.xml <?xml version="1.0" encoding=&qu ...

  8. EBR内容解析

    原先博客放弃使用,几篇文章搬运过来 EBR(Extended Boot Record)即扩展分区引导记录.类似于主引导记录MBR.因为MBR的四条分区信息的限制,可以使用EBR方便扩展. 它的结构与M ...

  9. 【慕课网实战】一、以慕课网日志分析为例 进入大数据 Spark SQL 的世界

    课程整套CDH相关的软件下载地址:http://archive.cloudera.com/cdh5/cdh/5/ cdh-5.7.0 生产或者测试环境选择对应CDH版本时,一定要采用尾号是一样的版本 ...

  10. jdk8中关于操作集合的一些新特性,遍历和排序操作

    jdk8增加了不少新的东西,在集合操作这块,就有如 lamda表达式,stream,sort,optional等新的类,主要涉及遍历和排序等方面,新特性提升了不少性能,我们开发就是要拥抱新事物,守着老 ...