0

I have a DTO which is an abstract class. When I am calling the Web API, I need to pass the child class. I followed this link Binding abstract action parameters in WebAPI but what I am not getting is where to put

config.Formatters.JsonFormatter.SerializerSettings.Converters.Add(
new PolymorphicProductConverter()
);

This code in my ASP.NET Core application.

Can anyone please help?

My models are like this

public abstract class HrBuildingComponentV1DTO
{
        public HrBuildingComponentV1DTO() { }

        public string Id { get; set; }
        public string Label { get; set; }
        public BuildingComponentType Type { get; set; }
        public int? Index { get; set; }
        public bool IsFilter { get; set; }
        public string SectionId { get; set; }

        public HrBuildingComponentV1DTO(HrBuildingComponentsV1 component)
        {
            Id = component.Id;
            Label = component.Label;
            Type = component.Type;
            Index = component.Index;
            IsFilter = component.IsFilter;
            SectionId = component.SectionId;
        }

         public abstract HrBuildingComponentsV1 ToModel();
}

public class HrTextBuildingComponentV1DTO : HrBuildingComponentV1DTO
{
    public string Value { get; set; }

    public HrTextBuildingComponentV1DTO() : base() { }

    public HrTextBuildingComponentV1DTO(HrTextBuildingComponentV1 model) : base(model)
    {
        Value = model.Value;
    }

    public override HrBuildingComponentsV1 ToModel()
    {
        return new HrTextBuildingComponentV1(this);
    }
}

Here is my custom converter

using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;

namespace HumanRisks.API.Helpers
{
    public class PolymorphicHrBuildingComponentConverter : JsonConverter
    {
        public override bool CanConvert(Type objectType)
        {
            return objectType == typeof(HrBuildingComponentV1DTO);
        }

        public override object ReadJson(JsonReader reader, Type objectType, 
            object existingValue, JsonSerializer serializer)
        {
            var obj = JObject.Load(reader);
            HrBuildingComponentV1DTO product;
            var pt = obj["Type"];
            if (pt == null)
            {
                throw new ArgumentException("Missing productType", "productType");
            }

            BuildingComponentType productType = pt.Value<BuildingComponentType>();
            if (productType == BuildingComponentType.Text)
            {
                product = new HrTextBuildingComponentV1DTO();
            }
            else if (productType == BuildingComponentType.TextArea)
            {
                product = new HrTextAreaBuildingComponentV1DTO();
            }
            else
            {
                throw new NotSupportedException("Unknown product type: " + productType);
            }

            serializer.Populate(obj.CreateReader(), product);
            return product;
        }

        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            throw new NotImplementedException();
        }
    }
}
5
  • 1
    You need to create your own converter class inheriting from JsonConverter. Commented Aug 3, 2022 at 5:43
  • I have already done that but where do I put it so that it can be use? I mean where to put the code to tell the api to use my converter? Commented Aug 3, 2022 at 5:50
  • I have added code for my custom converter as well Commented Aug 3, 2022 at 6:05
  • 1
    If you wan to know how to let the auto model binding to use custom jsonconverter, I suggest you could add it via addcontroller method like this: services.AddControllers().AddJsonOptions(options => { options.JsonSerializerOptions.Converters.Add(new PolymorphicHrBuildingComponentConverter ()); }); Commented Aug 3, 2022 at 10:00
  • I was using NewtonSoft and that was having issue with JsonSoft. Was able to fix it like this services.AddControllersWithViews().AddNewtonsoftJson(options => { options.SerializerSettings.Converters.Add(new PolymorphicDisplayLogicConverter()); options.SerializerSettings.Converters.Add(new PolymorphicHrBuildingComponentConverter()); }); Commented Aug 4, 2022 at 10:13

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.