Netcore webapi action swagger response返回参数使用匿名类型

问题:action中返回匿名对象时,swagger只能按强类型生成返回值描述

解决办法:使用roslyn在内存中动态执行代码,使用json.net反序列化匿名对象,向swagger返回动态匿名对象

效果:

Netcore webapi action swagger response返回参数使用匿名类型

Netcore webapi action swagger response返回参数使用匿名类型

Netcore webapi action swagger response返回参数使用匿名类型

   

Netcore webapi action swagger response返回参数使用匿名类型

   

Swaager在描述控制器的方法时,可以使用以下方法

<response code="400">如果id为空</response>

[ProducesResponseType(typeof(ResponseT<User>), 200)]

Openapi json如下

Netcore webapi action swagger response返回参数使用匿名类型

生成效果如下图

Netcore webapi action swagger response返回参数使用匿名类型

上述方法必须存在强类型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>匿名类型描述串

/// </param>

/// <example>new {id=1,name=""}</example>

/// <param></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;

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zgjdys.html