1

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

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

}

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

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

What I want is a way to serialize it to sub_AssignedToCompanyId@odata.bind (which i've done using JsonProperty("sub_AssignedToCompanyId@odata.bind"). 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?

Sundeep S
  • 51
  • 1
  • 4
  • According to [this post](https://github.com/domaindrivendev/Swashbuckle.AspNetCore/issues/669#issuecomment-377353228), if you've set a `JsonProperty` attribute for a property, that's what Swagger is going to use as a display value. I don't think Swagger supports showing one value which differs from the underlying json property. The point point of Swagger is to show a developer _exactly_ what values they need to provide. If what is shown is different that what is required, that defeats the purpose of having the page in the first place. – gunr2171 Jun 24 '19 at 20:25
  • I understand that, but in this case, it makes no sense to show "@odata.bind" to my end users. To the users of my api, it's just an id of the company it's assigned to. Anyway, thanks for the answer. – Sundeep S Jun 24 '19 at 20:29
  • You've asked two questions, but the rule on stack overflow is [one question per post](https://meta.stackexchange.com/q/222735). Can you split your question up into two posts? I could probably answer #2 but not #1. – dbc Jun 24 '19 at 20:46

3 Answers3

3

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

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

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.

Dan D
  • 2,493
  • 15
  • 23
0

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

    }
dkokkinos
  • 361
  • 2
  • 9