Home > Software design >  Generic property type to dynamically assign type
Generic property type to dynamically assign type

Time:11-26

I am expecting JSON object from an API which is like:

{
   "header":{
      "message_type":"message_type",
      "notification_type":"notification_type"
   },
   "body":{
      "id":"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
      "related_entity_type":"inbound_funds",
   }
}

The problem is that body can have any number and type of props. And, I have corresponding C# Models for each and every Body type. Is there any efficient way to parse and Deserialize these objects to relevant C# Models, dynamically?

I tried this, bus then Body doesn't desterilize at runtime.

public class PushNotification : Body
{
    [JsonProperty("header")]
    public Header Header { get; set; }

    [JsonProperty("body")]
    public Body Body { get; set; }
}

public class Body
{
}

CodePudding user response:

As an alternate approach, you can use JObject from Newtonsoft.Json to parse dynamic json. It can be read from JObject using key value pair

JObject jsonString= JObject.Parse(inputJson);
var id=jsonString["body"]["id"];

CodePudding user response:

Thank you everyone who took time to help me resolve this. Jegan Maria, Selvin and, Jochem!!

I managed to resolve it using dynamic type and factory!

Here are the code samples

API Layer:

using var reader = new StreamReader(Request.Body, Encoding.UTF8);

            var content = await reader.ReadToEndAsync();

            var data = (JObject)JsonConvert.DeserializeObject(content)!;

            var message_Type = data.SelectToken("header.message_type")!.Value<string>()!;

            _factory.Type = message_Type;
            var notification = _factory.CreateNotificationType();

            var dynamicObject = JsonConvert.DeserializeObject<dynamic>(content)!;
           
            notification = dynamicObject.ToObject(notification.GetType());

            

            return Ok(notification);

Here is the Factory Method:

public class PushNotificationFactory : IPushNotificationFactory

{ public string Type { get; set; }

public dynamic CreateNotificationType()
{        
    var type = Type switch
    {
        "cash_manager_transaction" => new PushNotification<CashManagerTransaction>(),
        _ => throw new NotImplementedException(),
    };

    return Activator.CreateInstance(type.GetType());
}

}

  • Related