Asp中的控制器和类列表. NET Web API
本文关键字:列表 NET Web API 控制器 Asp | 更新日期: 2023-09-27 18:17:03
我想访问我的web api中的所有控制器。假设我有两个控制器和两个类;
Foo :
string fooId
string fooName
酒吧:
string barId
string barName
Sample1Controller :
Get(int fooId)
Post([FromBody] Foo foo)
Sample2Controller :
Get(int barId)
Post([FromBody] Bar bar)
我想列出我的控制器,Foo和Bar类的属性。我该怎么做呢?
:
我想为移动应用程序创建请求和响应类。例如,如果我远程访问这些细节,我可以为java或objective-c创建请求和响应类。
您可以使用ApiExplorer
类,这是一个专门为Web api生成文档的类。
通常用于生成HTML帮助页面,但没有什么可以阻止您创建更机器可读的输出,如JSON或XML。如果您通过API操作方法公开输出,您将获得取决于请求类型的输出,就像任何其他API方法一样。
这里有一篇关于创建帮助页面的好文章,但是除了HTML之外,关于输出任何东西的材料并不多。不幸的是ApiExplorer类是不可序列化的,所以你不能只是返回一个调用GetApiExplorer()
的结果,但它是微不足道的足以创建我们自己的类是可序列化的,填充它们,然后从一个API动作返回那些。
可以通过"GlobalConfiguration.Configuration.Services.GetApiExplorer().ApiDescriptions
"访问ApiExplorer
类。这将返回一个Collection<ApiDescription>
,其中包含有关控制器、动作和参数的信息。如果您愿意,它甚至可以用于访问任何///summary
注释中的文档。这取决于你想要的信息和你想要的格式,但下面是一个使用这种方法可以实现的示例:
首先,我创建了一个类来存储Action方法的细节:
[DataContract]
public class ActionMethod
{
[DataMember]
public string Name { get; set; }
[DataMember]
public List<Parameter> Parameters { get; set; }
[DataMember]
public string SupportedHttpMethods { get; set; }
}
注意SupportedHttpMethods
只是一个string
而不是List<T>
。您可能想将其改进为List<T>
,但对于本例,我只是用逗号分隔它们,以使稍微更容易。
ActionMethod
类有一个List<Parameter>
,看起来像这样:
[DataContract]
public class Parameter
{
[DataMember]
public string Name { get; set; }
[DataMember]
public string Source { get; set; } //where we pass the parameter when calling the action
[DataMember]
public string Type { get; set; }
[DataMember]
public List<Parameter> SubParameters { get; set; }
}
注意,SubParameters
用于存储复杂类型的成员变量的类型。我只捕获了一个层次的深度,但如果需要的话,扩展它是很容易的。
然后,我创建了一个新的Controller
与一个动作方法,将返回我们的API信息作为List<ActionMethod>
。请注意,我已经添加了属性[ApiExplorerSettings(IgnoreApi = true)]
,它告诉ApiExplorer
忽略这个Controller
中的任何内容,因此我们不会在文档控制器上生成文档(这可以工作,但对我来说太元了!)。
[ApiExplorerSettings(IgnoreApi = true)]
public class HelpController : ApiController
{
public List<ActionMethod> Get()
{
var apiActions = new List<ActionMethod>();
Collection<ApiDescription> apiDescriptions = GlobalConfiguration
.Configuration
.Services
.GetApiExplorer()
.ApiDescriptions;
foreach (var api in apiDescriptions)
{
List<Parameter> parameters = new List<Parameter>();
//get the parameters for this ActionMethod
foreach (var parameterDescription in api.ParameterDescriptions)
{
Parameter parameter = new Parameter()
{
Name = parameterDescription.Name,
Source = parameterDescription.Source.ToString(),
Type = parameterDescription.ParameterDescriptor.ParameterType.ToString(),
SubParameters = new List<Parameter>()
};
//get any Sub-Parameters (for complex types; this should probably be recursive)
foreach (var subProperty in parameterDescription.ParameterDescriptor.ParameterType.GetProperties())
{
parameter.SubParameters.Add(new Parameter()
{
Name = subProperty.Name,
Type = subProperty.PropertyType.ToString()
});
}
parameters.Add(parameter);
}
//add a new action to our list
apiActions.Add(new ActionMethod()
{
Name = api.ActionDescriptor.ControllerDescriptor.ControllerName,
Parameters = parameters,
SupportedHttpMethods = string.Join(",", api.ActionDescriptor.SupportedHttpMethods)
});
}
return apiActions;
}
}
我们可以在/api/help
访问api文档。以问题中的控制器和操作方法为例,请求JSON给出如下响应:
[
{
"Name":"Bar",
"Parameters":[
{
"Name":"barId",
"Source":"FromUri",
"Type":"System.Int32",
"SubParameters":[
]
}
],
"SupportedHttpMethods":"GET"
},
{
"Name":"Bar",
"Parameters":[
{
"Name":"bar",
"Source":"FromBody",
"Type":"ApiTest.Controllers.Bar",
"SubParameters":[
{
"Name":"barId",
"Source":null,
"Type":"System.String",
"SubParameters":null
},
{
"Name":"barName",
"Source":null,
"Type":"System.String",
"SubParameters":null
}
]
}
],
"SupportedHttpMethods":"POST"
},
{
"Name":"Foo",
"Parameters":[
{
"Name":"fooId",
"Source":"FromUri",
"Type":"System.Int32",
"SubParameters":[
]
}
],
"SupportedHttpMethods":"GET"
},
{
"Name":"Foo",
"Parameters":[
{
"Name":"foo",
"Source":"FromBody",
"Type":"ApiTest.Controllers.Foo",
"SubParameters":[
{
"Name":"fooId",
"Source":null,
"Type":"System.String",
"SubParameters":null
},
{
"Name":"fooName",
"Source":null,
"Type":"System.String",
"SubParameters":null
}
]
}
],
"SupportedHttpMethods":"POST"
}
]
和请求XML给我们:
<?xml version="1.0" encoding="UTF-8"?>
<ArrayOfActionMethod xmlns="http://schemas.datacontract.org/2004/07/ApiTest.Controllers"
xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<ActionMethod>
<Name>Bar</Name>
<Parameters>
<Parameter>
<Name>barId</Name>
<Source>FromUri</Source>
<SubParameters />
<Type>System.Int32</Type>
</Parameter>
</Parameters>
<SupportedHttpMethods>GET</SupportedHttpMethods>
</ActionMethod>
<ActionMethod>
<Name>Bar</Name>
<Parameters>
<Parameter>
<Name>bar</Name>
<Source>FromBody</Source>
<SubParameters>
<Parameter>
<Name>barId</Name>
<Source i:nil="true" />
<SubParameters i:nil="true" />
<Type>System.String</Type>
</Parameter>
<Parameter>
<Name>barName</Name>
<Source i:nil="true" />
<SubParameters i:nil="true" />
<Type>System.String</Type>
</Parameter>
</SubParameters>
<Type>ApiTest.Controllers.Bar</Type>
</Parameter>
</Parameters>
<SupportedHttpMethods>POST</SupportedHttpMethods>
</ActionMethod>
<ActionMethod>
<Name>Foo</Name>
<Parameters>
<Parameter>
<Name>fooId</Name>
<Source>FromUri</Source>
<SubParameters />
<Type>System.Int32</Type>
</Parameter>
</Parameters>
<SupportedHttpMethods>GET</SupportedHttpMethods>
</ActionMethod>
<ActionMethod>
<Name>Foo</Name>
<Parameters>
<Parameter>
<Name>foo</Name>
<Source>FromBody</Source>
<SubParameters>
<Parameter>
<Name>fooId</Name>
<Source i:nil="true" />
<SubParameters i:nil="true" />
<Type>System.String</Type>
</Parameter>
<Parameter>
<Name>fooName</Name>
<Source i:nil="true" />
<SubParameters i:nil="true" />
<Type>System.String</Type>
</Parameter>
</SubParameters>
<Type>ApiTest.Controllers.Foo</Type>
</Parameter>
</Parameters>
<SupportedHttpMethods>POST</SupportedHttpMethods>
</ActionMethod>
</ArrayOfActionMethod>
关于ApiExplorer
类的更多信息可以在MSDN上找到
要获取包含控制器的程序集,请向其中一个控制器添加操作,以便在执行时可以获取程序集:
var types = GetType().Assembly.GetTypes();
现在可以遍历这些类型并进行测试,看看它是什么类型。如果你所有的控制器都实现了一个共同的接口或者扩展了一个共同的类等等……您还可以测试名称空间..
例如:for (var t in types)
{
if (t.IsSubClassOf(typeof( ApiController))){ .... }
}
下面是一个教程/示例:
如何在实现IMyInterface的引用中获取所有类型