Home > front end >  Deserialize JSON message from Service Bus Queue Trigger to C# Object
Deserialize JSON message from Service Bus Queue Trigger to C# Object

Time:04-26

I have an Azure Function as below:

public class SaveProductDataToDatabase
{
    private readonly IProductRepository _productRepository;

    public SaveProductDataToDatabase(IProductRepository productRepository)
    {
        _productRepository = productRepository;
    }

    [FunctionName("SaveProductDataToDatabase")]
    public void Run([ServiceBusTrigger("product-data-dev-01", Connection = "ServiceBusConnectionString")] string myQueueItem, ILogger log)
    {
        log.LogInformation($"Processed message: {myQueueItem}");
            
        // TODO : JSON Mapping will be added here once Service Bus Queue is Up and Running.
        _productRepository.Add(new Domain.Entities.Product());
    }
}

Here, myQueueItem will return a complex nested JSON string

{
  "metadata": {
    "origin": "xyz-data",
    "dateCreated": "2022-03-17T12:48:04.511Z"
  },
  "version": 6,
  "messageId": "a44f23aa-bab4-4eed-a235-5820d966f669",
  "sWrapper": {
    "sid": "zzavqw18",
    "identifiers": [
      {
        "alias": "si-sku",
        "value": [
          "8086300"
        ]
      }
    ]
  },
  "itemType": "ITEM",
  "master": {
    "masterSource": "XYZ_PDS",
    "title": {
      "mainTitle": "XYZ - All Time Greats"
    },
    "description": {
      "longDescription": "XYZ - All Time Greats",
      "shortDescription": "XZY - All Time Greats"
    },
    "classification": {
      "identifier": "1pvfy"
    }
  }
}

In this, I want to extract sWrapper.sid, sWrapper.identifiers.value, and classification.identifier properties and assign it plain C# object. And that object will be passed to _productRepository.Add(<C# object goes here>);

How to handle this mapping? what's the best approach? Please advice.

CodePudding user response:

there are multiple approaches. option 1 - use class to deserialize and use class properties using Newtonsoft.Json

JsonConvert.DeserializeObject<CLASS>(JSON_STRING)

option 2 use System.Text.Json.Nodes to access directly to node

var jn = JsonNode.Parse(j)["sWrapper"].Dump("node");
jn["sid"].GetValue<string>().Dump("Value of SID");

enter image description here

P.S> again, there are may approaches... then create a new class and populate class properties with values and pass object to fuction.

CodePudding user response:

You can deserialize your JSON string to the following Model structure using Newtonsoft package and then you can access the properties and then create a Model class to hold your required data that you want to send to your repository:

You can refer to a working program here: https://dotnetfiddle.net/7VHalV

using System;
using Newtonsoft.Json;
using System.Collections.Generic;
                    
public class Program
{
    public static void Main()
    {
        MyData mydata=new MyData();
        string jsonString = "{'metadata':{'origin':'xyz-data','dateCreated':'2022-03-17T12:48:04.511Z'},'version':6,'messageId':'a44f23aa-bab4-4eed-a235-5820d966f669','sWrapper':{'sid':'zzavqw18','identifiers':[{'alias':'si-sku','value':['8086300']}]},'itemType':'ITEM','master':{'masterSource':'XYZ_PDS','title':{'mainTitle':'XYZ - All Time Greats'},'description':{'longDescription':'XYZ - All Time Greats','shortDescription':'XZY - All Time Greats'},'classification':{'identifier':'1pvfy'}}}";
        
        var result =JsonConvert.DeserializeObject<Root>(jsonString);
        mydata.sid=result.sWrapper.sid;
        //Console.WriteLine(result.sWrapper.sid);
        
        foreach(var item in result.sWrapper.identifiers)
        {
            //Console.WriteLine(item.alias);
            foreach(var item1 in item.value)
            {
                mydata.ivalue=item1;
                //Console.WriteLine(item1);
            }
        }
        mydata.cidentifier=result.master.classification.identifier;
        //Console.WriteLine(result.master.classification.identifier);
        
        Console.WriteLine(mydata.sid);
        Console.WriteLine(mydata.ivalue);
        Console.WriteLine(mydata.cidentifier);
        
        //Finally send to your repository
        //_productRepository.Add(mydata);
        
    }
}

public class Metadata
{
    public string origin { get; set; }
    public DateTime dateCreated { get; set; }
}

public class Identifier
{
    public string alias { get; set; }
    public List<string> value { get; set; }
}

public class SWrapper
{
    public string sid { get; set; }
    public List<Identifier> identifiers { get; set; }
}

public class Title
{
    public string mainTitle { get; set; }
}

public class Description
{
    public string longDescription { get; set; }
    public string shortDescription { get; set; }
}

public class Classification
{
    public string identifier { get; set; }
}

public class Master
{
    public string masterSource { get; set; }
    public Title title { get; set; }
    public Description description { get; set; }
    public Classification classification { get; set; }
}

public class Root
{
    public Metadata metadata { get; set; }
    public int version { get; set; }
    public string messageId { get; set; }
    public SWrapper sWrapper { get; set; }
    public string itemType { get; set; }
    public Master master { get; set; }
}

//To hold the data from the de-serialization
public class MyData
{
    public string sid { get; set; }
    public string ivalue { get; set; }
    public string cidentifier { get; set; } 
}

Output:

zzavqw18
8086300
1pvfy
  • Related