Netcore webapi action swagger response返回参数使用匿名类型
问题:action中返回匿名对象时,swagger只能按强类型生成返回值描述
解决办法:使用roslyn在内存中动态执行代码,使用json.net反序列化匿名对象,向swagger返回动态匿名对象
效果:




Swaager在描述控制器的方法时,可以使用以下方法
<response code="400">如果id为空</response>
或
[ProducesResponseType(typeof(ResponseT<User>),
												200)]
Openapi json如下

生成效果如下图

上述方法必须存在强类型user
代码
@@@code
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
public class AnonymousTypeProducesResponseTypeAttribute : Microsoft.AspNetCore.Mvc.ProducesResponseTypeAttribute
{
public AnonymousTypeProducesResponseTypeAttribute(string typeJson, int statusCode) : base(getAnonymousType(typeJson), statusCode)
{
}
/// <summary>
///
/// </summary>
/// <param name="typeJson">匿名类型描述串
/// </param>
/// <example>new {id=1,name=""}</example>
/// <param name="statusCode"></param>
static System.Type getAnonymousType(string typeJson)
{
var code = @"
public class Result {
public System.Type GetType2(){
var t = Newtonsoft.Json.JsonConvert.DeserializeAnonymousType(""{}"", #T#);
return t.GetType();
}
}
".Replace("#T#", typeJson.Replace("'", @""""));
List<PortableExecutableReference> refList = new List<PortableExecutableReference>();
refList.Add(MetadataReference.CreateFromFile(typeof(object).Assembly.Location));
refList.Add(MetadataReference.CreateFromFile(typeof(Newtonsoft.Json.JsonConvert).Assembly.Location));
refList.Add(MetadataReference.CreateFromFile(typeof(System.Runtime.AssemblyTargetedPatchBandAttribute).Assembly.Location));
refList.Add(MetadataReference.CreateFromFile(System.IO.Path.Combine(System.IO.Path.GetDirectoryName(typeof(object).Assembly.Location), "netstandard.dll")));
var tree = CSharpSyntaxTree.ParseText(code);
var compilation = CSharpCompilation.Create("test")
.WithOptions(new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary))
.AddReferences(refList.ToArray()).AddSyntaxTrees(tree);
using (var stream = new MemoryStream())
{
var emitResult = compilation.Emit(stream);
if (emitResult.Success)
{
stream.Seek(0, SeekOrigin.Begin);
var assembly = Assembly.Load(stream.ToArray());
var typeResult = assembly.GetType("Result");
var m = Activator.CreateInstance(typeResult);
var Type = m.GetType();
return typeResult.GetMethod("GetType2").Invoke(m, null) as Type;
}
}
return null;
}
}
@@#
使用
@@@code
[HttpGet("Dept/Get")]
[AnonymousTypeProducesResponseType(@"new {Code=0,Msg='',Data=new []{new {id=0,name=''}}}", 200)]
public object DeptGet()
{
return new
{
Code = 0,
Msg = string.Empty,
Data = _context. Group.Select(r => new
{
id = r. ID,
name = r. Name
}).ToList()
};
}
@@#
另一种借助元组实现的方法
花了大量时间获取属性名没有结果,泛型传递时的方法获取 不到TupleElementNamesAttribute,只能走动态方法获取 返回值 ,再利用TupleElementNamesAttribute获取 名称
@@@code
public class ResponseT<T>
{
//有效 [JsonProperty("haaa")]
public int Code { get; set; }
// 无效 [JsonConverter(typeof(Q.DevExtreme.Tpl.Json.IPAddressConverter))]
public string Msg { get; set; }
public T Data { get; set; }
public T[] GetData()
{
//泛型,丢失名称信息,没有TupleElementNamesAttribute属性
return new[] { Data };
}
public (int a, string b) GetData2()
{
//可以使用下列方法获得名称
//Type t = typeof(C);
//MethodInfo method = t.GetMethod(nameof(C.M));
//var attr = method.ReturnParameter.GetCustomAttribute<TupleElementNamesAttribute>();
//string[] names = attr.TransformNames;
return (1, "2");
}
}
@@#
使用
@@@code
[ProducesResponseType(typeof(ResponseT<(int id,string name)>), 400)]
@@E
Netcore webapi action swagger response返回参数使用匿名类型的更多相关文章
- 使用ActionFilterAttribute 记录 WebApi Action 请求和返回结果记录
		使用ActionFilterAttribute 记录 WebApi Action 请求和返回结果记录 C#进阶系列——WebApi 异常处理解决方案 [ASP.NET Web API教程]4.3 AS ... 
- Web API系列(四) 使用ActionFilterAttribute 记录 WebApi Action 请求和返回结果记录
		转自:https://www.cnblogs.com/hnsongbiao/p/7039666.html 需要demo在github中下载: https://github.com/shan333cha ... 
- Asp.NetCore WebApi 引入Swagger
		一.创建一个Asp.NetCore WebApi 项目 二.引入NuGet包 SwashBuckle.AspNetCore 三.在项目属性配置中设置 四.修改项目的启动文件Startup.cs 1). ... 
- .NetCore WebApi利用Swagger文档实现选择文件上传
		介绍 实现这个功能主要还是依赖过滤器 在Swagger中利用 IOperationFilter 操作来实现文件上传 与之前处理结合Idr4授权一样的处理方式,不同的是授权处理的是Security,而文 ... 
- .NetCore WebApi——基于JWT的简单身份认证与授权(Swagger)
		上接:.NetCore WebApi——Swagger简单配置 任何项目都有权限这一关键部分.比如我们有许多接口.有的接口允许任何人访问,另有一些接口需要认证身份之后才可以访问:以保证重要数据不会泄露 ... 
- .NetCore WebApi——Swagger简单配置
		在前后端分离的大环境下,API接口文档成为了前后端交流的一个重点.Swagger让开发人员摆脱了写接口文档的痛苦. 官方网址:https://swagger.io/ 在.Net Core WebApi ... 
- .NetCore WebApi —— Swagger版本控制
		目录: .NetCore WebApi——Swagger简单配置 .NetCore WebApi——基于JWT的简单身份认证与授权(Swagger) .NetCore WebApi —— Swagge ... 
- VS2012 Unit Test(Void, Action, Func) —— 对无返回值、使用Action或Func作为参数、多重载的方法进行单元测试
		[提示] 1. 阅读文本前希望您具备如下知识:了解单元测试,了解Dynamic,熟悉泛型(协变与逆变)和Lambda,熟悉.NET Framework提供的 Action与Func委托.2.如果您对单 ... 
- 对无返回值、使用Action或Func作为参数、多重载的方法进行单元测试
		VS2012 Unit Test(Void, Action, Func) —— 对无返回值.使用Action或Func作为参数.多重载的方法进行单元测试 [提示] 1. 阅读文本前希望您具备如下知识: ... 
随机推荐
- 别找了,这可能是全网最全的鸿蒙(OpenHarmony)刷机指南
			目录: 1. 配置编译环境 2. 编译HarmonyOS源代码 3. 烧录HarmonyOS 4.下载文中资源 5.作者文章合集 摘要:相信很多同学都玩过鸿蒙(HarmonyOS)了,不过估计大多数同 ... 
- Js和JQuery基础
			1.JavaScript的组成 CMAScript (核心):规定了JS的语法和基本对象 DOM 文档对象模型:处理网页内容的方法和接口 BOM 浏览器对象模型:与浏览器交互的方法和接口 2.Java ... 
- Charles 抓取https 包
			1. Recording Settings中 include 添加 host , port端口为443 2. SSL Proxying Settings 选中 Enable SSL Proxyin ... 
- JavaScript 模拟 sleep
			用 JS 实现沉睡几秒后再执行,有好几种方式,但都不完美,以下是我感觉比较好的一种方式 function sleep(time) { return new Promise((resolve) => ... 
- 后端程序员之路 21、一个cgi的c++封装
			在"3.fastcgi.fastcgi++"中,我们了解了cgi,也尝试了fastcgi++,这里,再记录一种对fastcgi的封装. 1.cgi接口层 request_t ... 
- go mod管理 init 和 包导入的关系
			你创建了一个文件的名字为:lisi001 如果你初始化项目名字为lisi, go mod init lisi 那么你导包的时候就得也用lisi import ( "lisi/path&quo ... 
- Linux自学之旅-基础命令(chown和chgrp)
			转: Linux自学之旅-基础命令(chown和chgrp) Linux自学之旅-基础命令(改变所有者与所属组的命令) 文章目录 前言 一.chown命令 二.chgrp命令 总结 前言 1.上一节我 ... 
- 剑指 Offer 12. 矩阵中的路径 + 递归 + 深搜 + 字符串问题
			剑指 Offer 12. 矩阵中的路径 题目链接 题目类似于迷宫的搜索. 需要注意的是,需要首先判断起始搜索的位置,可能有多个起点,都需要一一尝试. 每轮迭代的时候记得将是否遍历标记数组还原为未遍历的 ... 
- python面试题总结
			Python语言特性 1. Python的函数参数传递  看两个如下例子,分析运行结果 #代码1 a = 1 def fun(a): a = 2 fun(a) print(a) #1 #代码2 a ... 
- [virtualenv][python] 环境管理——对 virtualenv 更轻便的封装
			virtualenv_simple_wrapper 如有错误,欢迎指出 Char-z 项目地址 gitee: virtualenv_simple_wrapper 使用说明 下载文件 virtualen ... 
