问题: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. [C#] 尝鲜.net6.0的C#代码热重载

    看到.NET 6 Preview 1 发布,里面"除了 XAML 热重载之外,还将支持 C# 代码的热重载"一句,觉得有必要试试看,因为XAML热重载功能用起来确实很爽. 首先要下 ...

  2. (1)MySQL进阶篇在linux环境下安装

    1.概述 对于mysql二进制安装,优点是可以安装到任何路径下,灵活性好,一台服务器可以安装多个mysql.缺点是已经编译过,性能不如源码编译得好,不能灵活定制编译参数.如果用户即不想安装最简单却不够 ...

  3. 1047 Student List for Course ——PAT甲级真题

    1047 Student List for Course Zhejiang University has 40,000 students and provides 2,500 courses. Now ...

  4. 微信小程序:标签字符串直接变成标签来显示要通过富文本技术

    rich-text标签存在nodes属性直接接受标签字符串

  5. 注册 Amazon Web Services(AWS) 账号,助园一臂之力

    感谢大家去年的大力支持,今年园子继续和 Amazon Web Services(AWS) 合作,只要您通过 博客园专属链接 注册一个账号(建议使用手机4G网络注册),亚马逊就会给园子收入,期待您的支持 ...

  6. Dos常用命令整理

    Dos常用命令整理 打开cmd的方法 开始菜单 -> 系统 -> 命令提示符 组合键Win+R打开运行 -> 输入cmd 在任意文件夹下Shift+鼠标右键 -> 在此处打开命 ...

  7. Docker镜像构建原理解析(不装docker也能构建镜像)

    在devops流程里面 构建镜像是一个非常重要的过程,一般构建镜像是写dockerfile文件然后通过docker client来构建的image. docker client 会先检查本地有没有im ...

  8. 这是你没见过的不一样的redis

    转: 这是你没见过的不一样的redis 提到Redis,大家一定会想到的几个点是什么呢? 高并发,KV存储,内存数据库,丰富的数据结构,单线程(6版本之前) 那么,接下来,上面提到的这些,都会一一给大 ...

  9. MarkFormat,一个在Word中使用Mark进行格式化的插件

    MarkFormat(标记格式化),是一款在Word中基于标记进行格式化的工具. 让我们看下具体效果. 首先是有标记的文本 点击格式化之后 点击去除标记之后(去除标记也会进行格式化) 如果想要恢复标记 ...

  10. 使用wireshark 抓取 http https tcp ip 协议进行学习

    使用wireshark 抓取 http https tcp ip 协议进行学习 前言 本节使用wireshark工具抓包学习tcp ip http 协议 1. tcp 1.1 tcp三次握手在wire ...