Asp.NET Web API 中的控制器和类列表

2024-04-01

我想访问我的 Web api 中的所有控制器。假设我有 2 个控制器和 2 个类;

Foo:

string fooId

string fooName

Bar:

string barId

string barName

样本1控制器:

Get(int fooId)

Post([FromBody] Foo foo)

样本2控制器:

Get(int barId)

Post([FromBody] Bar bar)

我想列出我的控制器、Foo 和 Bar 类及其属性。我怎样才能做到这一点 ?

Update:

我想为移动应用程序创建请求和响应类。例如,如果我远程访问这些详细信息,我可以为 java 或 Objective-C 创建请求和响应类。


你可以使用ApiExplorerclass 是专门为生成 Web API 文档而设计的类。

通常它用于生成 HTML 帮助页面,但没有什么可以阻止您创建更机器可读的输出,例如 JSON 或 XML。如果您通过 API 操作方法公开输出,您将像任何其他 API 方法一样根据请求的类型获得输出。

有一篇关于创建帮助页面的好文章here http://blogs.msdn.com/b/yaohuang1/archive/2012/05/13/asp-net-web-api-introducing-iapiexplorer-apiexplorer.aspx但是除了 HTML 之外,没有太多关于输出任何内容的材料。不幸的是,ApiExplorer 类不可序列化,因此您不能仅返回调用的结果GetApiExplorer()但创建我们自己的可序列化类、填充它们然后从 API 操作返回这些类已经足够简单了。

您可以访问ApiExplorer类通过使用GlobalConfiguration.Configuration.Services.GetApiExplorer().ApiDescriptions。这将返回一个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>但对于这个例子,我只是用逗号分隔它们以创造生命slightly easier.

The 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使用一个 action 方法,它将返回我们的 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 文档:/api/help。使用您在问题中提供的控制器和操作方法作为示例,请求 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 http://msdn.microsoft.com/en-us/library/system.web.http.description.apiexplorer%28v=vs.118%29.aspx.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Asp.NET Web API 中的控制器和类列表 的相关文章

  • 在结构中使用 typedef 枚举并避免类型混合警告

    我正在使用 C99 我的编译器是 IAR Embedded workbench 但我认为这个问题对于其他一些编译器也有效 我有一个 typedef 枚举 其中包含一些项目 并且我向该新类型的结构添加了一个元素 typedef enum fo
  • 秒表有最长运行时间吗?

    多久可以Stopwatch在 NET 中运行 如果达到该限制 它会回绕到负数还是从 0 重新开始 Stopwatch Elapsed返回一个TimeSpan From MSDN https learn microsoft com en us
  • 不支持将数据直接绑定到存储查询(DbSet、DbQuery、DbSqlQuery)

    正在编码视觉工作室2012并使用实体模型作为我的数据层 但是 当页面尝试加载时 上面提到的标题 我使用 Linq 语句的下拉控件往往会引发未处理的异常 下面是我的代码 using AdventureWorksEntities dw new
  • ASP.NET MVC:这个业务逻辑应该放在哪里?

    我正在开发我的第一个真正的 MVC 应用程序 并尝试遵循一般的 OOP 最佳实践 我正在将控制器中的一些简单业务逻辑重构到我的域模型中 我最近一直在阅读一些内容 很明显我应该将逻辑放在域模型实体类中的某个位置 以避免出现 贫血域模型 反模式
  • 如何使用 ICU 解析汉字数字字符?

    我正在编写一个使用 ICU 来解析由汉字数字字符组成的 Unicode 字符串的函数 并希望返回该字符串的整数值 五 gt 5 三十一 gt 31 五千九百七十二 gt 5972 我将区域设置设置为 Locale getJapan 并使用
  • 用于登录 .NET 的堆栈跟踪

    我编写了一个 logger exceptionfactory 模块 它使用 System Diagnostics StackTrace 从调用方法及其声明类型中获取属性 但我注意到 如果我在 Visual Studio 之外以发布模式运行代
  • 不同枚举类型的范围和可转换性

    在什么条件下可以从一种枚举类型转换为另一种枚举类型 让我们考虑以下代码 include
  • 堆栈溢出:堆栈空间中重复的临时分配?

    struct MemBlock char mem 1024 MemBlock operator const MemBlock b const return MemBlock global void foo int step 0 if ste
  • HttpContext.GetGlobalResourceObject 始终返回 null

    我在 App GlobalResources 文件夹中创建了两个文件 SiteResources en US resx SiteResources sp SP resx 两者都包含 SiteTitleSeparator 的值 这是我想要做的
  • 带动态元素的 WPF 启动屏幕。如何?

    我是 WPF 新手 我需要一些帮助 我有一个加载缓慢的 WPF 应用程序 因此我显示启动屏幕作为权宜之计 但是 我希望能够在每次运行时更改屏幕 并在文本区域中显示不同的引言 这是一个生产力应用程序 所以我将使用非愚蠢但激励性的引言 当然 如
  • 不可勾选的单选按钮与专有的复选框

    从 UI 角度来看 是拥有一组具有取消选中功能的单选按钮更好 还是拥有一组独占的复选框 意味着一次只能选中一个 更好 Update 我没想到对此会有如此负面的反应 如果我给出一个更接近其使用方式的示例 也许会有所帮助 我有一个充满数据绑定内
  • 重载<<的返回值

    include
  • 显示UnityWebRequest的进度

    我正在尝试使用下载 assetbundle统一网络请求 https docs unity3d com ScriptReference Networking UnityWebRequest GetAssetBundle html并显示进度 根
  • while 循环中的 scanf

    在这段代码中 scanf只工作一次 我究竟做错了什么 include
  • 如何在 C 中调用采用匿名结构的函数?

    如何在 C 中调用采用匿名结构的函数 比如这个函数 void func struct int x p printf i n p x 当提供原型的函数声明在范围内时 调用该函数的参数必须具有与原型中声明的类型兼容的类型 其中 兼容 具有标准定
  • 如何序列化/反序列化自定义数据集

    我有一个 winforms 应用程序 它使用强类型的自定义数据集来保存数据进行处理 它由数据库中的数据填充 我有一个用户控件 它接受任何自定义数据集并在数据网格中显示内容 这用于测试和调试 为了使控件可重用 我将自定义数据集视为普通的 Sy
  • Windows 窗体:如果文本太长,请添加新行到标签

    我正在使用 C 有时 从网络服务返回的文本 我在标签中显示 太长 并且会在表单边缘被截断 如果标签不适合表单 是否有一种简单的方法可以在标签中添加换行符 Thanks 如果您将标签设置为autosize 它会随着您输入的任何文本自动增长 为
  • 覆盖子类中的字段或属性

    我有一个抽象基类 我想声明一个字段或属性 该字段或属性在从该父类继承的每个类中具有不同的值 我想在基类中定义它 以便我可以在基类方法中引用它 例如覆盖 ToString 来表示 此对象的类型为 property field 我有三种方法可以
  • C# 成员变量继承

    我对 C 有点陌生 但我在编程方面有相当广泛的背景 我想做的事情 为游戏定义不同的 MapTiles 我已经像这样定义了 MapTile 基类 public class MapTile public Texture2D texture pu
  • C++ 中类级 new 删除运算符的线程安全

    我在我的一门课程中重新实现了新 删除运算符 现在我正在使我的代码成为多线程 并想了解这些运算符是否也需要线程安全 我在某处读到 Visual Studio 中默认的 new delete 运算符是线程安全的 但这对于我的类的自定义 new

随机推荐