【问题标题】:Ignore [FromForm] data from rendering on swagger在 swagger 上渲染时忽略 [FromForm] 数据
【发布时间】:2021-08-06 18:12:25
【问题描述】:

我正在开发 .Net 5 Web API,我正在使用 Swashbuckle,当我在我的模型上使用 [JsonIgnore] 时,它可以很好地渲染我的 JSON

型号:

    public partial class ApplicationDocument : BaseModel
    {
        public int id { get; set; }
        public int document_id { get; set; }
        public int application_id { get; set; }
        [NotMapped]
        public string name { get; set; }
        [NotMapped]
        public string documentUrl { get; set; }
        [JsonIgnore]
        public virtual Application application { get; set; }
        [JsonIgnore]
        public virtual Document document { get; set; }
    }

JSON

{
  "applicationDocument": {
    "dateCreated": "2021-05-17T13:08:08.934Z",
    "dateModified": "2021-05-17T13:08:08.934Z",
    "createdBy": "string",
    "modifiedBy": "string",
    "isActive": true,
    "isDeleted": true,
    "id": 0,
    "document_id": 0,
    "application_id": 0,
    "name": "string",
    "documentUrl": "string"
  },
  "fileDocument": "string"
}

问题是当我在控制器中使用 [FromForm] 属性时,[JsonIgnore] 对我不起作用,它呈现了每个字段,甚至是导航字段

控制器

        [HttpPost]
        [Route("[controller]/AddApplicationDocument")]
        public BaseResponse AddApplicationDocument([FromForm] ApplicationDocumentViewModel ApplicationDocumentViewModel)
        {
            return _ApplicationDocument.AddApplicationDocument(ApplicationDocumentViewModel);
        }

【问题讨论】:

  • 没那么多,他想忽略它没有属性,但我已经在使用它,它不起作用
  • 你能详细说明它为什么不适合你吗?其中一个答案是“使用 System.Text.Json.Serialization 命名空间中的 JsonIgnore。Newtonsoft.Json 中的 JsonIgnore 将不起作用。”
  • 当它是一个普通的帖子时它工作正常,当它是一个 [FromForm] 帖子(多部分)表单时它不起作用 - 见附图
  • 我认为你在使用[FromForm]时需要[BindNever]属性。

标签: c# asp.net-core asp.net-web-api swagger .net-5


【解决方案1】:

我有一个想法给你,希望你能用它解决你的问题。

首先,创建这个属性:

[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]
public class SwaggerIgnoreAttribute : Attribute
{
}

然后,为 swagger 选项创建一个 OperationFilter 和一个 SchemaFilter :

public class IgnorePropertyFilter : IOperationFilter
    {
        public void Apply(OpenApiOperation operation, OperationFilterContext context)
        {
            if (context.ApiDescription == null || operation.Parameters == null)
                return;

            if (!context.ApiDescription.ParameterDescriptions.Any())
                return;


            var excludedProperties = context.ApiDescription.ParameterDescriptions.Where(p =>
                p.Source.Equals(BindingSource.Form));

            if (excludedProperties.Any())
            {

                foreach (var excludedPropertie in excludedProperties)
                {
                    foreach (var customAttribute in excludedPropertie.CustomAttributes())
                    {
                        if (customAttribute.GetType() == typeof(SwaggerIgnoreAttribute))
                        {
                            for (int i = 0; i < operation.RequestBody.Content.Values.Count; i++)
                            {
                                for (int j = 0; j < operation.RequestBody.Content.Values.ElementAt(i).Encoding.Count; j++)
                                {
                                    if (operation.RequestBody.Content.Values.ElementAt(i).Encoding.ElementAt(j).Key ==
                                        excludedPropertie.Name)
                                    {
                                        operation.RequestBody.Content.Values.ElementAt(i).Encoding
                                            .Remove(operation.RequestBody.Content.Values.ElementAt(i).Encoding
                                                .ElementAt(j));
                                        operation.RequestBody.Content.Values.ElementAt(i).Schema.Properties.Remove(excludedPropertie.Name);


                                    }
                                }
                            }

                        }
                    }
                }

            }
        }
    }
public class SwaggerIgnoreFilter : ISchemaFilter
    {
        public void Apply(OpenApiSchema schema, SchemaFilterContext schemaFilterContext)
        {
            if (schema.Properties.Count == 0)
                return;

            const BindingFlags bindingFlags = BindingFlags.Public |
                                              BindingFlags.NonPublic |
                                              BindingFlags.Instance;
            var memberList = schemaFilterContext.Type // In v5.3.3+ use Type instead
                                .GetFields(bindingFlags).Cast<MemberInfo>()
                                .Concat(schemaFilterContext.Type // In v5.3.3+ use Type instead
                                .GetProperties(bindingFlags));

            var excludedList = memberList.Where(m =>
                                                m.GetCustomAttribute<SwaggerIgnoreAttribute>()
                                                != null)
                                         .Select(m =>
                                             (m.GetCustomAttribute<JsonPropertyAttribute>()
                                              ?.PropertyName
                                              ?? m.Name.ToCamelCase()));

            foreach (var excludedName in excludedList)
            {
                if (schema.Properties.ContainsKey(excludedName))
                    schema.Properties.Remove(excludedName);
            }
        }

    }

然后,将它们都添加到启动类中进行swagger配置:

services.AddSwaggerGen(options =>
{
   options.SchemaFilter<SwaggerIgnoreFilter>();
   options.OperationFilter<IgnorePropertyFilter>();
}

最后,您可以将 [SwaggerIgnore] 用于您不会在 swagger 中看到的每个属性:

public partial class ApplicationDocument : BaseModel
{
    public int id { get; set; }
    public int document_id { get; set; }
    public int application_id { get; set; }
        
    public string name { get; set; }
        
    public string documentUrl { get; set; }

    [SwaggerIgnore]
    public virtual Application application { get; set; }
    [SwaggerIgnore]
    public virtual Document document { get; set; }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-08-05
    • 1970-01-01
    • 2012-01-31
    • 2017-01-28
    • 1970-01-01
    • 1970-01-01
    • 2013-09-06
    • 1970-01-01
    相关资源
    最近更新 更多