您好,欢迎来到二三四教育网。
搜索
您的当前位置:首页Swagger for Asp.net 应用笔记

Swagger for Asp.net 应用笔记

来源:二三四教育网

简介

使用中如果碰到任何问题欢迎评论,一起讨论解决

项目引入Swagger

使用nuget加入Swashbuckle的引用。
Paste_Image.png

安装好以后,在App_Start目录下,会有一个SwaggerConfig.cs文件,SwaggerConfig类通过[assembly: PreApplicationStartMethod(typeof(SwaggerConfig), "Register")]启动时运行。

SwaggerConfig简单介绍

SwaggerConfig.cs文件会自动添加到项目的App_Start目录下,代码本身包含大量注释掉的代码,清除后,代码如下:

 public class SwaggerConfig
   {
       public static void Register()
       {
           var thisAssembly = typeof(SwaggerConfig).Assembly;
            GlobalConfiguration.Configuration
               .EnableSwagger(c =>//用于启用和设置Swagger的配置信息。
                   {
                       c.SingleApiVersion("v1", "Cxx.xxx.Web");       
                      //a#                
                   })
               .EnableSwaggerUi(c =>
                   {//用于启用UI界面上的东西。
                      //b#
                  });
       }
   }
支持XML注释

使用Swagger的目的就是希望把代码中方法和类型的注释自动导出来。在Swashbuckle中,很简单。

  • 相关工程需要生成XML文档


    Paste_Image.png
  • 在Swagger.Config的Register方法的EnableSwagger匿名函数中加上对应的XML文件(可以添加在//a#代码后面。)

var baseDirectory = AppDomain.CurrentDomain.BaseDirectory +"\\bin\\"; var commentsFileName = Assembly.GetExecutingAssembly().GetName().Name + ".XML"; var commentsFile = commentsFileName); c.IncludeXmlComments(commentsFile);

上述代码把Web工程的XML注释加入到Swagger中。一般我们会把viewmodel或者其他类型定义在不同的工程中,通过下面的代码可以继续加入其它xml注释文件。(对应功能需要启用XML文档文件生成)
"CrXX.XX.xml"));

实现默认调用参数

Swagger本身支持直接调用,但是调用参数需要手动编写,一个比较简单的办法是自定义一个attribute,给viewmodel的参数加上默认参数。

  • 首先增加一个Swagger属性如下图:

     public class SwaggerDefaultValue : Attribute
     {
          public string Name { get; set; }
          public string Value { get; set; }
          public SwaggerDefaultValue(string value)
          {
              this.Value = value;
          }
    
          public SwaggerDefaultValue(string name, string value) : this(value)
          {
              this.Name = name;
          }
    }
    
  • 增加一个AddDefaultValues类,如下面代码

      public class AddDefaultValues : IOperationFilter
      {
        public void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription     apiDescription)
        {
 
            IDictionary<string, object> parameterValuePairs =
            GetParameterValuePairs(apiDescription.ActionDescriptor);
            if (operation?.parameters != null)
            {
 
                foreach (var param in operation.parameters)
                {
                    if (param.schema != null && param.schema.@ref != null)
                    {
                        string schemaName = param.schema.@ref.Split('/').LastOrDefault();
                        if (schemaRegistry.Definitions.ContainsKey(schemaName))
                            foreach (var props in schemaRegistry.Definitions[schemaName].properties)
                            {
                                if (parameterValuePairs.ContainsKey(props.Key.ToLower()))//默认会转换为camelcase,所以强行转为小写
                                    props.Value.@default = parameterValuePairs[props.Key.ToLower()];//默认会转换为camelcase,所以强行转为小写
                            }
                    }
                    var parameterValuePair = parameterValuePairs.FirstOrDefault(p =>   p.Key.IndexOf(param.name, StringComparison.InvariantCultureIgnoreCase) >= 0);
                    param.@default = parameterValuePair.Value;
                }
            }
        }
 
      private IDictionary<string, object> GetParameterValuePairs(HttpActionDescriptor actionDescriptor)
      {
        IDictionary<string, object> parameterValuePairs = new Dictionary<string, object>();
 
        foreach (SwaggerDefaultValue defaultValue in actionDescriptor.GetCustomAttributes<SwaggerDefaultValue>())
        {
            parameterValuePairs.Add(defaultValue.Name, defaultValue.Value);
        }
 
        foreach (var parameter in actionDescriptor.GetParameters())
        {
            if (!parameter.ParameterType.IsPrimitive)
            {
                InitialType(parameterValuePairs, parameter.ParameterType);
            }
        }
 
        return parameterValuePairs;
      }
 
      void InitialType(IDictionary<string, object> parameterValuePairs, Type t)
      {
        foreach (PropertyInfo property in t.GetProperties())
        {
            var defaultValue = GetDefaultValue(property);
 
            if (defaultValue != null)
            {
 
                parameterValuePairs.Add(property.Name.ToLower(), defaultValue);//默认会转换为camelcase,所以强行转为小写
            }
        }
      }
 
      private static object GetDefaultValue(PropertyInfo property)
      {
        var customAttribute = property.GetCustomAttributes<SwaggerDefaultValue>().FirstOrDefault();
 
        if (customAttribute != null)
        {
            return customAttribute.Value;
        }
 
        return null;
      }  
}
  • 在Swagger.Config的Register方法的EnableSwagger匿名函数中对应的过滤器(可以添加在//a#代码后面。)
    c.OperationFilter<AddDefaultValues>();

  • 在具体的调用参数上加上默认参数,在swagger的界面上就会有默认参数啦。

 public class CheckMobile
 {
       [SwaggerDefaultValue("13482894351")]
       [Required]
       public string Mobile { get; set; }   
}
实现Oauth2 API的调用

我们的WebAPI基于OAuth2的验证,所以Swagger上并不能直接调用。如果希望Swagger能直接调用OAuth2保护的API。

  • 增加一个js到Web工程中, zhe


    Paste_Image.png

*js的内容如下

$('#input_apiKey').change(function () {
    var key = $('#input_apiKey')[0].value;
    var credentials = key.split(':'); //username:password expected
    $.ajax({
        url: "/Token",
        type: "post",
        contenttype: 
        data: "grant_type=password&username=" + credentials[0] + "&password=" + credentials[1],
        success: function (response) {
            
            var bearerToken = 'Bearer ' + response.access_token;
            swaggerUi.api.clientAuthorizations.add('key', new SwaggerClient.ApiKeyAuthorization('Authorization', bearerToken, 'header'));
            
        },
        error: function (xhr, ajaxoptions, thrownerror) {
            alert("输入的用户名密码不对,不能登陆!");
        }
    });
});```
*在Swagger.config 的Register方法的EanbleSwaggerUI匿名函数中加上对应的JS,可以加在//b#后面
`c.InjectJavaScript(typeof(SwaggerConfig).Assembly, "CrXXX.XX.SwaggerLogin.js");`
>CrXXX.XX 需要改成web工程的名字

在Swagger界面上的API_Key输入框输入oauth2的用户名密码即可登录.

  来实现, 我会尽快翻译.
使用上面的方法要注意的是,在IdentityServer中的设置里面,Client需要
允许重定向到 "http://WebAPI地址/swagger/ui/o2c-html"

##### Swagger API文档的效果图

Copyright © 2019- how234.cn 版权所有 赣ICP备2023008801号-2

违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务