0

I have implemented/used simple JsonConverter to represent the object value as string on swagger UI, which works as expected.

Converter Attribute :

 public class Dependency
{        
    public string Name { get; set; }
   
    [JsonProperty("Range")]        
    [JsonConverter(typeof(RangeConverter))]
    public RangeRange { get; set; }
}

Converter :

 public class RangeConverter : JsonConverter<Range>
    {
        public override void WriteJson(JsonWriter writer, Range value, JsonSerializer serializer)
        {
            writer.WriteValue(value.ToString());
        }
       
        public override Range ReadJson(JsonReader reader, Type objectType, Range existingValue, bool hasExistingValue, JsonSerializer serializer)
        {
            //some logic
            return existingValue;
        }
    }

Request Body:

enter image description here

Swagger Request example which is being shown in request body :

 [ExcludeFromCodeCoverage]
public class CreateDtoExample : IExamplesProvider<CreateDto>
{
    /// <inheritdoc/>
    public CreateDto GetExamples()
    {
       Service service = new Service
        {
            Code = "string",
            AdditionalProperties = new Dictionary<string, JToken>()
            {
                { "Property1", "Value1" },
                { "Property2", "Value2" },
            },
        };

       CreateDto createDtoExample = new createDto
        {
            Name = "Model",                
            Dependencies = new List<Dependencies>
            {
                new Dependencies
                {
                    Name = "string",
                    VersionRange = VersionRange.Parse("[1,2)"),
                },
            },              
            AdditionalProperties = new Dictionary<string, JToken>()
            {
                { "Property1", "Value1" },
                { "Property2", "Value2" },
            },
        };

        return createDtoExample;
    }
}

But while Posting above request body . I want to save whole Range object with its properties to Cosmos DB.

Due to JsonConveter Implemenation, only string value representation of object is getting saved. i.e. Range": "[1.0.0, 2.0.0)"

Range Class have following properties :

 "Range": {
    "IsFloating": true,
    "Float": {
      "HasMinVersion": true,
      "MinVersion": "string",
      "FloatBehavior": 0,
      "OriginalReleasePrefix": "string"
    },
    "OriginalString": "string",
    "HasLowerBound": true,
    "HasUpperBound": true,
    "HasLowerAndUpperBounds": true,
    "IsMinInclusive": true,
    "IsMaxInclusive": true,
    "MaxVersion": "string",
    "MinVersion": "string"

I want to save this Object as is to Cosmos after De-serializing string value posted (keeping string representation on swagger UI).

S2K
  • 1,185
  • 3
  • 27
  • 55
  • Assuming that `Range` is [`System.Range`](https://learn.microsoft.com/en-us/dotnet/api/system.range), how are you registering when serializing in swagger, and when posting to Cosmos? Or if not, can you share a [mcve] showing `Range` and how the converter is applied? – dbc Aug 07 '23 at 06:51
  • @dbc Updated the question with SwaggerRequest example. I am using Nuget.Versioning package. – S2K Aug 07 '23 at 15:22
  • @dbc Added how converter is applied too. – S2K Aug 07 '23 at 15:41
  • You can use a [custom contract resolver](https://www.newtonsoft.com/json/help/html/contractresolver.htm#CustomIContractResolverExamples) to cancel a `JsonConverter` applied to a property, see for instance the converter from [this answer](https://stackoverflow.com/a/71531470/3744182) to [Custom JsonConvertor that also serializes it's value minus one of it's properties](https://stackoverflow.com/q/71529340/3744182). (The resolver includes a `HashSet converterTypesToIgnore` of converters to remove.) – dbc Aug 07 '23 at 21:19
  • Cosmos doesn't expose it's internal `JsonSerializerSettings` though so it seems you may need to make your own `CosmosSerializer`. [This answer](https://stackoverflow.com/a/57066220) to [How do I configure Cosmos DB .NET 3.0 SDK to serialize with camel case?](https://stackoverflow.com/q/56084282) links to a [gist](https://gist.github.com/richstokoe/c82fc831c6b4020926f5b5f772f7cd70) by richstokoe which you could use as a model for your own `CosmosSerializer`. – dbc Aug 07 '23 at 21:19
  • @dbc I have created one more model without JsonConverter Atrribute to class and then used AutoMapper to map theclasses. It does save Range properties to comosDB. But when i try to read response from cosmos by casting it to reponse Object it fails with exception : ""Message": "Unable to find a constructor to use for type NuGet.Versioning.VersionRange. A class should either have a default constructor, one constructor with arguments or a constructor marked with the JsonConstructor attribute. Path 'Dependencies[0].Range.IsFloating', – S2K Aug 07 '23 at 21:23
  • Using a second DTO with automapper is a good solution. As for the *Unable to find a constructor* problem: the format on stack overflow is to ask [one question per post](https://meta.stackexchange.com/q/222735), so you should ask another question about that, and include a [mcve]. – dbc Aug 07 '23 at 21:25
  • Sure. Thanks for your responses. I will add a question. – S2K Aug 07 '23 at 21:25
  • @dbc question : https://stackoverflow.com/questions/76855318/unable-to-find-a-constructor-to-use-for-type-nuget-versioning-versionrange – S2K Aug 07 '23 at 21:41
  • @dbc can you have a look at this question ? https://stackoverflow.com/questions/76863589/how-to-hide-exclude-property-from-swaggerresponse-model-not-request-but-respons – S2K Aug 09 '23 at 16:16

0 Answers0