[WebAPI,Swagger]Swagger_Body以及Query轉換成FormData

WebAPI產生的Swagger , 將裡頭Body , 或是WebAPI上原本的Model加上FormUri , 轉換成FormData

參考資料: http://tahirhassan.blogspot.com/2017/12/web-apiswagger-file-upload.html


 

1.首先 為了不影響各個API的變化 , 我們先建立一個Attribute

2.建立完成後,將要轉換的Api套上此Attribute

備註:想要下面的參數的話只需要在第一步驟加入建構子跟屬性就可以帶入參數

3.但這樣子還是不會執行到,因為還沒做關連,所以我們要建立Swagger專用的類別

    /// <summary>
    /// Class SwaggerParameterOperationFilter.
    /// </summary>
    /// <seealso cref="Swashbuckle.Swagger.IOperationFilter" />
    public class SwaggerParameterOperationFilter: Swashbuckle.Swagger.IOperationFilter
    {
        /// <summary>
        /// Applies the specified operation.
        /// </summary>
        /// <param name="operation">The operation.</param>
        /// <param name="schemaRegistry">The schema registry.</param>
        /// <param name="apiDescription">The API description.</param>
        public void Apply(Swashbuckle.Swagger.Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription)
        {
            //確認是否有加入此Attribute 如果有的話就做
            var requestAttributes = apiDescription.GetControllerAndActionAttributes<SwaggerParameterAttribute>();
            if (requestAttributes.Any())
            {
                operation.parameters = operation.parameters ?? new List<Parameter>();

                //foreach (var item in requestAttributes)
                //{
                //    item.Name

                //}

                //取得Action的參數
                var getActionParameters = apiDescription.ActionDescriptor.GetParameters();
                foreach (var item in getActionParameters)
                {
                    //如果底層型別為Object
                    if(item.ParameterType.BaseType.Name==typeof(object).Name)
                    {
                        //檢查是否有此Object 有才做 , 如果是string 在CheckObjectName這邊正常會判定為False , string底層型別為Object,item.ParameterType.Name = String
                        var checkObjectName = schemaRegistry.Definitions.ContainsKey(item.ParameterType.Name);
                        if(checkObjectName)
                        {
                            //取得Object裡面的屬性
                            var data = schemaRegistry.Definitions[item.ParameterType.Name];
                            foreach (var item2 in data.properties)
                            {
                                //加進Swagger裡面
                                operation.parameters.Add(new Parameter
                                {
                                    name = item2.Key,
                                    description = item2.Value.description,
                                    @in = "formData",
                                    required = false,
                                    type = item2.Value.type,
                                    @enum = item2.Value.@enum
                                });
                            }
                            //移除Swagger內容
                            schemaRegistry.Definitions.Remove(item.ParameterType.Name);
                            //移除Swagger上Body的
                            operation.parameters.Remove(operation.parameters.FirstOrDefault(x => x.@in == "body"));
                            //為了預防邊foreach邊Remove會造成的錯誤所以新建New一個List
                            var parameterList = new List<Parameter>(operation.parameters.ToList());
                            foreach (var parameter in operation.parameters.Where(x=>x.@in == "query"))
                            {
                                parameterList.Remove(parameter);
                            }
                            
                            operation.parameters = parameterList;

                            if (apiDescription.ParameterDescriptions.Any(x => x.Name == item.ParameterName))
                            {
                                apiDescription.ParameterDescriptions.Remove(apiDescription.ParameterDescriptions.FirstOrDefault(x => x.Name == item.ParameterName));
                            }
                        }
                    }
                }
            }
        }
    }

備註:以上我都附上註解了,也就是將Model Object裡面的屬性取出來個別建立Formdata後再將Model Object整個移除

4. 最後套入SwaggerConfig裡面即可完成Swagger跟Attribute的連結