问题: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返回参数使用匿名类型的更多相关文章

  1. 使用ActionFilterAttribute 记录 WebApi Action 请求和返回结果记录

    使用ActionFilterAttribute 记录 WebApi Action 请求和返回结果记录 C#进阶系列——WebApi 异常处理解决方案 [ASP.NET Web API教程]4.3 AS ...

  2. Web API系列(四) 使用ActionFilterAttribute 记录 WebApi Action 请求和返回结果记录

    转自:https://www.cnblogs.com/hnsongbiao/p/7039666.html 需要demo在github中下载: https://github.com/shan333cha ...

  3. Asp.NetCore WebApi 引入Swagger

    一.创建一个Asp.NetCore WebApi 项目 二.引入NuGet包 SwashBuckle.AspNetCore 三.在项目属性配置中设置 四.修改项目的启动文件Startup.cs 1). ...

  4. .NetCore WebApi利用Swagger文档实现选择文件上传

    介绍 实现这个功能主要还是依赖过滤器 在Swagger中利用 IOperationFilter 操作来实现文件上传 与之前处理结合Idr4授权一样的处理方式,不同的是授权处理的是Security,而文 ...

  5. .NetCore WebApi——基于JWT的简单身份认证与授权(Swagger)

    上接:.NetCore WebApi——Swagger简单配置 任何项目都有权限这一关键部分.比如我们有许多接口.有的接口允许任何人访问,另有一些接口需要认证身份之后才可以访问:以保证重要数据不会泄露 ...

  6. .NetCore WebApi——Swagger简单配置

    在前后端分离的大环境下,API接口文档成为了前后端交流的一个重点.Swagger让开发人员摆脱了写接口文档的痛苦. 官方网址:https://swagger.io/ 在.Net Core WebApi ...

  7. .NetCore WebApi —— Swagger版本控制

    目录: .NetCore WebApi——Swagger简单配置 .NetCore WebApi——基于JWT的简单身份认证与授权(Swagger) .NetCore WebApi —— Swagge ...

  8. VS2012 Unit Test(Void, Action, Func) —— 对无返回值、使用Action或Func作为参数、多重载的方法进行单元测试

    [提示] 1. 阅读文本前希望您具备如下知识:了解单元测试,了解Dynamic,熟悉泛型(协变与逆变)和Lambda,熟悉.NET Framework提供的 Action与Func委托.2.如果您对单 ...

  9. 对无返回值、使用Action或Func作为参数、多重载的方法进行单元测试

    VS2012 Unit Test(Void, Action, Func) —— 对无返回值.使用Action或Func作为参数.多重载的方法进行单元测试 [提示] 1. 阅读文本前希望您具备如下知识: ...

随机推荐

  1. NGK钱包真的安全吗?

    对于数字资产持有者而言,资产的安全永远是首要的,因而数字钱包的安全性显得尤为重要.数字钱包分为冷钱包和热钱包两种.热钱包叫做在线钱包,而冷钱包被称为离线钱包,也叫硬件钱包.数字钱包一旦被盗,被追回的概 ...

  2. 我眼中的价值币——NGK(下)

    跨链交互方案并不是区块链世界中的一个新课题.自比特币诞生揭开智能合约的序幕之后,跨链交互的需求便产生了.但是,经过十年的发展,市场中的跨链解决方案进展缓慢,究之原因有以下几个方面. 首先,区块链的去中 ...

  3. banner自用图床2

  4. eclipse快速定位当前类所在位置

    如何快速的找到一个类并且定位它所在的位置呢?这里以搜索Menu类为例说明. 可以通过CTRL + SHIFT +R的组合键,输入Menu 双击Menu.java即可跳转到对应的类上,但此时还不知道此类 ...

  5. 按照阿里巴巴规范创建Java线程池

    前言 Executors Executors 是一个Java中的工具类.提供工厂方法来创建不同类型的线程池. 常用方法: 1.newSingleThreadExecutor   介绍:创建一个单线程的 ...

  6. yum install valgrind.x86_64

    Reference: https://cloudlinux.zendesk.com/hc/en-us/articles/115004075294-Fix-rpmdb-Thread-died-in-Be ...

  7. 第41天学习打卡(死锁 Lock synchronized与Lock的对比 线程协作 使用线程池)

    死锁 多个线程各自占有一些共享资源,并且互相等待其他线程占有的资源才能运行,而导致两个或者多个线程都在等待对方释放资源,都停止执行的情形.某一个同步块同时拥有"两个以上对象的锁"时 ...

  8. 记录vue springboot 跨域采坑

    vue配置 域名src\main.js要与config\index.js一样 var axios = require('axios')axios.defaults.baseURL = 'http:// ...

  9. 后端程序员之路 51、A Tour of Go-1

    # A Tour of Go    - go get golang.org/x/tour/gotour    - https://tour.golang.org/    # welcome    - ...

  10. Docker安装Openvas

    目录 安装 在本机内运行 在局域网内运行 关闭 参考 安装 ➜ ~ docker search openvas NAME DESCRIPTION STARS OFFICIAL AUTOMATED mi ...