Update existing key value if present and then deserialize json to POCO efficiently I have a json string ProcessValue in which I need to extract a particular key (client_id) value and then I need to encode that value using HttpUtility.HtmlEncode and put it back in the same JSON string. ProcessValue is one of the header name which has a json value in it.
Below is my code which does that but I am deserializing twice looks like. Is there any way to improve below code?
ProcessValue = GetHeader(headers, PROCESS_DATA); // LINE A
if (!string.IsNullOrWhiteSpace(ProcessValue))
{
    dynamic jsonObject = Newtonsoft.Json.JsonConvert.DeserializeObject(ProcessValue);
    if (jsonObject.client_id != null)
    {
        var value = jsonObject.client_id;
        jsonObject.client_id = HttpUtility.HtmlEncode(value);
        var modifiedJsonString = Newtonsoft.Json.JsonConvert.SerializeObject(jsonObject);
        ProcessValue = modifiedJsonString;
    }
    ProcCustomer = DeserializeJson&lt;ProcCustomer&gt;(ProcessValue);
}

private T DeserializeJson&lt;T&gt;(string str) where T : new()
{
    try
    {
        return JsonSerializer.Deserialize&lt;T&gt;(str);
    }
    catch (Exception e)
    {
        return new T();
    }
}

Here ProcessValue at LINE A is:
{&quot;key1&quot;:&quot;value1&quot;,&quot;key2&quot;:&quot;value2&quot;,&quot;key3&quot;:&quot;value3&quot;,&quot;key4&quot;:&quot;value4&quot;,&quot;key5&quot;:&quot;value6&quot;,&quot;client_id&quot;:&quot;HÃ¤nzendes&quot;}

I am extracting client_id value and then encoding it and after that putting it back to same json. And then I am deserializing this modified json value to ProcCustomer POCO. ProcCustomer is the POCO class which holds all the fields value. So I am deserializing and serializing to get my updated json string ProcessValue and then I deserialize this json to ProcCustomer POCO class.
There are places where we use ProcessValue json string directly as it is one of the header value and using ProcCustomer POCO fields as well so that is why I was doing above things. I wanted to see if there is anything I can do to optimize my above code where I don't have to deserialize and then serialize and then again deserialize to put it in POCO?
Also I am mixing Utf8Json library with Newton json library. I prefer to use Utf8 json library for both serialization and deserialization in my above code.
Even if ProcessValue is used as string in other objects, why you don't just deserialize it once across the class, then use the POCO object directly. Then, serialize it whenever needed.
So, in your question this would be valid :
ProcessValue = GetHeader(headers, PROCESS_DATA); // LINE A

if (!string.IsNullOrWhiteSpace(ProcessValue))
{
    ProcCustomer = DeserializeJson&lt;ProcCustomer&gt;(ProcessValue);

    if (ProcCustomer != null &amp;&amp; !string.IsNullOrWhiteSpace(ProcCustomer.ClientId))
    {
        ProcCustomer.ClientId = HttpUtility.HtmlEncode(ProcCustomer.ClientId);
    }
}

This way you only deserialized it once in this scope. Also, if the client_id is always needs to be encoded using HttpUtility.HtmlEncode you could modify the POCO and do this for instance :
public class ProcCustomer
{
    //.. other properties 
    
    [JsonProperty(&quot;client_id&quot;)]
    public string ClientId 
    { 
        get =&gt; ClientId;
        set
        {
            if(!string.IsNullOrEmpty(value))
            {
                ClientId = HttpUtility.HtmlEncode(value);
            }
            else 
            {
                ClientId = value;
            }
        } 
    } 
}

With this, your code will be shorter as you only need to deserialize, the rest will be updated according to the POCO logic!
Answering the comments :
working with ProcessValue as string, will make things difficult to handle. What I suggested is to use the deserialized object (which is the POCO in your case), then work with it like any object. When you want to pass it to the HttpClient header, just serialize it, to pass it as sting.
The main idea is to work with objects, and not with the strings! use the strings only when required. This way you'll have a better coding experience.
For example, we can modify the POCO and override the ToString method like this :
public class ProcCustomer
{
    public override string ToString() {
        return Newtonsoft.Json.JsonConvert.SerializeObject(this);
    }
}

Now, when we want to add it to the header we can do this (example) :
// assuming we've already updated the POCO values
// and we need to add it to the HttpClient header 
using (var client = new HttpClient{ BaseAddress = baseAddress })
{
    client.DefaultRequestHeaders.Add(&quot;&quot;, ProcCustomer.ToString());
    
    using (var response = await client.GetAsync(Url))
    {
        var responseData = await response.Content.ReadAsStringAsync();
    }
}

If you can't modify the POCO, then you can add extensions like this :
// implement the extensions 
public class JsonExtensions
{
    public T JsonDeserialize&lt;T&gt;(this string str) where T : class
    {
        try
        {
            return Newtonsoft.Json.JsonConvert.DeserializeObject&lt;T&gt;(str);
        }
        catch (Exception e)
        {
            return default;
        }
    }
    
    public string JsonSerialize&lt;T&gt;(this T obj) where T : class
    {
        try
        {
            return Newtonsoft.Json.JsonConvert.SerializeObject&lt;T&gt;(obj);
        }
        catch (Exception e)
        {
            return null;
        }
    }
}

You can use the extensions instead of ToString approach
// EXAMPLE : 

ProcessValue = GetHeader(headers, PROCESS_DATA); // LINE A

if (!string.IsNullOrWhiteSpace(ProcessValue))
{
    ProcCustomer = ProcessValue.DeserializeJson&lt;ProcCustomer&gt;();

    if (ProcCustomer != null &amp;&amp; !string.IsNullOrWhiteSpace(ProcCustomer.ClientId))
    {
        ProcCustomer.ClientId = HttpUtility.HtmlEncode(ProcCustomer.ClientId);
        
        ProcessValue = ProcCustomer.JsonSerialize(); 
        // or do it directly in the httpClient instead of ProcCustomer.ToString()
        
    }
}