【问题标题】:Change Swagger Property Names更改 Swagger 属性名称
【发布时间】:2019-06-24 20:21:30
【问题描述】:

问。 1 我正在尝试将实体推入 CRM。 json 看起来像这样:

{
    "sub_AssignedToCompanyId@odata.bind": "/accounts(f52f9dd7-35e5-e711-813b-480fcff40721)"

}

现在,我的 C# 类上有一个名为 AssignedToCompany 的属性,如下所示:

[JsonProperty(PropertyName = "sub_AssignedToCompanyId@odata.bind")]
public int AssignedToCompany{ get; set; }

我想要的是一种将它序列化为 sub_AssignedToCompanyId@odata.bind 的方法(我已经使用 JsonProperty("sub_AssignedToCompanyId@odata.bind") 完成了。但是那么招摇定义看起来不太好。我想要这个属性的大摇大摆的定义说“assignedToCompanyId”。有没有办法做到这一点?我正在使用.Net Framework Web API。

Q.2 而且,有没有办法可以翻译这个输入: f52f9dd7-35e5-e711-813b-480fcff40721

到这个输出: /accounts(f52f9dd7-35e5-e711-813b-480fcff40721)

在序列化过程中自动?

【问题讨论】:

  • 根据this post,如果您为属性设置了JsonProperty 属性,那么这就是Swagger 将用作显示值的内容。我不认为 Swagger 支持显示一个与底层 json 属性不同的值。 Swagger 的重点是向开发人员确切地显示他们需要提供哪些价值。如果显示的内容与要求的内容不同,那么首先就违背了拥有该页面的目的。
  • 我明白这一点,但在这种情况下,向我的最终用户显示“@odata.bind”是没有意义的。对于我的 api 的用户来说,它只是分配给它的公司的 id。无论如何,谢谢你的回答。
  • 你已经问了两个问题,但是堆栈溢出的规则是one question per post。你能把你的问题分成两个帖子吗?我可能会回答 #2 但不会回答 #1。

标签: c# json swagger


【解决方案1】:

您可以使用IOperationFilterISchemaFilterIDocumentFilter。选择最适合您的需求。

ISchemaFilter 的示例可能是:

public class ODataTypeSchemaFilter : ISchemaFilter
{
   private const string propToRename = "sub_AssignedToCompanyId@odata.bind";

   public void Apply(Schema schema, SchemaRegistry schemaRegistry, Type, type)
   {
      if (type == typeof(MyObject))
      {
         // adding new schema property, and removing the old one
         schema.properties.Add(nameof(MyObject.AssignedToCompany), schema.properties[propToRename]);
         schema.properties.Remove(propToRename);
      }
   }
}

public class MyObject
{
   [JsonProperty(PropertyName = "sub_AssignedToCompanyId@odata.bind")]
   public int AssignedToCompany { get; set; }
}

这是一项强大的功能,如果不正确更改架构,可能会导致其他问题。有关更多信息,请参阅 Swagger 文档。根据我的经验,我已经使用了所有这三种方法,只需找到最适合您需求的一种即可。

【讨论】:

    【解决方案2】:

    你也可以试试这个。以前的答案对我不起作用,但确实如此。 但是我建议在模型的属性名称中使用所需的名称,因为这样您可能还必须解决在请求发生时将 json 反序列化为对象的问题。

    public class CustomNameSchema : ISchemaFilter
        {
            public void Apply(OpenApiSchema schema, SchemaFilterContext context)
            {
                if (schema?.Properties == null)
                {
                    return;
                }
    
                if (schema.Properties.Any())
                {
                    foreach (var propType in context.Type.GetProperties().Where(x => x.CustomAttributes != null && x.CustomAttributes.Any()))
                    {
                        var schemaProp = schema.Properties.FirstOrDefault(x => x.Key.Equals(propType.Name, StringComparison.InvariantCultureIgnoreCase));
                        string newName = propType.GetCustomAttribute<DataMemberAttribute>()?.Name;
                        if (string.IsNullOrEmpty(newName))
                            continue;
    
                        if (schemaProp.Value.Enum != null && schemaProp.Value.Enum.Any())
                        {
                            for (int i = 0; i < schemaProp.Value.Enum.Count; i++)
                            {
                                OpenApiString curr = schemaProp.Value.Enum[i] as OpenApiString;
                                var memberInfo = propType.PropertyType.GetMember(curr.Value).FirstOrDefault();
                                string newValue = memberInfo.GetCustomAttribute<EnumMemberAttribute>()?.Value;
                                if (string.IsNullOrWhiteSpace(newValue))
                                    continue;
                                OpenApiString newStr = new OpenApiString(newValue);
                                schemaProp.Value.Enum.Remove(curr);
                                schemaProp.Value.Enum.Insert(0, newStr);
                            }
                        }
    
                        var newSchemaProp = new KeyValuePair<string, OpenApiSchema>(newName, schemaProp.Value);
                        schema.Properties.Remove(schemaProp);
                        schema.Properties.Add(newSchemaProp);
                    }
                }
    
                var objAttribute = context.Type.GetCustomAttribute<DataContractAttribute>();
                if (objAttribute != default && objAttribute?.Name?.Length > 0)
                {
                    schema.Title = objAttribute.Name;
                }
            }
    
        }
    

    【讨论】:

      【解决方案3】:

      对我来说,只需添加 [System.Text.Json.Serialization.JsonPropertyName("property")] 即可解决问题

      using System.Text.Json.Serialization;
      
      [Serializable]
      public class Foo
      {
          [JsonPropertyName("bar")]
          public long Bar{ get; set; }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-01-18
        • 2020-04-19
        • 2023-03-02
        • 1970-01-01
        • 1970-01-01
        • 2017-06-24
        • 2017-07-28
        • 1970-01-01
        相关资源
        最近更新 更多