Sundeep S
Sundeep S

Reputation: 51

Change Swagger Property Names

Q. 1 I'm trying to push an entity into CRM. The json looks like this:

{
    "[email protected]": "/accounts(f52f9dd7-35e5-e711-813b-480fcff40721)"

}

Now, my C# class has a property on it called AssignedToCompany, looks like this:

[JsonProperty(PropertyName = "[email protected]")]
public int AssignedToCompany{ get; set; }

What I want is a way to serialize it to [email protected] (which i've done using JsonProperty("[email protected]"). But then the swagger definition doesn't look good. I want the swagger definition of this property to say "assignedToCompanyId". Is there anyway to do this? I'm using .Net Framework Web API.

Q.2 And, is there a way that I can translate this input: f52f9dd7-35e5-e711-813b-480fcff40721

to this output: /accounts(f52f9dd7-35e5-e711-813b-480fcff40721)

automatically during serialization?

Upvotes: 1

Views: 10370

Answers (3)

Jonathan Gobato
Jonathan Gobato

Reputation: 33

For me, just add [System.Text.Json.Serialization.JsonPropertyName("property")] resolved the problem

using System.Text.Json.Serialization;

[Serializable]
public class Foo
{
    [JsonPropertyName("bar")]
    public long Bar{ get; set; }
}

Upvotes: 3

dkokkinos
dkokkinos

Reputation: 411

You can try also this one. The previous answers did not work for me but this did. However I recommend to use the desired names in you model's property names because then maybe you will have to address also the problem of deserializing the json to the objects when a request happens.

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;
            }
        }

    }

Upvotes: 1

Dan D
Dan D

Reputation: 2523

You can use IOperationFilter, ISchemaFilter or IDocumentFilter. Whichever best suits your needs.

An example of an ISchemaFilter could be:

public class ODataTypeSchemaFilter : ISchemaFilter
{
   private const string propToRename = "[email protected]";

   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 = "[email protected]")]
   public int AssignedToCompany { get; set; }
}

This is a powerful feature, changing the schema could potentially cause other problems if not done properly. See Swagger documentation for more info. I've used all three in my experience, just find which suits your needs best.

Upvotes: 1

Related Questions