-2

i have json string as

{"AccountNo":"345234533466","AuthValue":"{\"TopUpMobileNumber\":\"345234533466\",\"VoucherAmount\":\"100\"}"}

to parse this string i have created class as

public class UserContext
{
    public string AccountNo { get; set; }
    public string AuthValue { get; set; }
}

in AuthValue it gives me output as {\"TopUpMobileNumber\":\"345234533466\",\"VoucherAmount\":\"100\"} which is absolutely correct. now i want to modify my class in such way that i want AuthValue in string format as well and in seprate member variable format.

so i modify my class in this way but it gives error

public class UserContext
{
    public string AccountNo { get; set; }
    public string AuthValue { get; set; }
    public Auth ????? { get; set; }
}

 public class Auth
{
    public string TopUpMobileNumber { get; set; }
    public string VoucherAmount { get; set; }
}

My requirement is

  1. AuthValue whole json string i required
  2. in another variable i want member wise values

Parsing Logic

UserContext conObj1 = new UserContext();
conObj1 = JsonConvert.DeserializeObject<UserContext>(context);

Note : No modification in json string is allowed.

Shaggy
  • 5,422
  • 28
  • 98
  • 163
  • Well yes, it would give you an error - for one thing because you're trying to declare two members with the same name. But it's fairly easy to fix, at least using JSON.NET. (Unfortunately I don't have time to post an answer right now...) – Jon Skeet Nov 07 '14 at 07:23
  • thing is if i modify my variable name i wont be able to parse `json` string – Shaggy Nov 07 '14 at 07:24
  • You're trying to use a single class to represent two different things - one where it's a string, and one where it's an object. It doesn't help that we don't know what you're using for JSON parsing. – Jon Skeet Nov 07 '14 at 07:25
  • @JonSkeet i m using `JsonConvert` – Shaggy Nov 07 '14 at 07:28
  • 1
    As an aside, using `SomeType x = new SomeType(); x = someExpression;` is almost always pointless. Just use `SomeType x = someExpression;`. Why create an object you don't need? – Jon Skeet Nov 07 '14 at 08:21

2 Answers2

3

I'm not very familiar with JsonConvert or Json.NET so I'm not sure what options are available for that. Personally I'd just call the deserializer again immediately afterwards.

UserContext conObj1 = new UserContext();
conObj1 = JsonConvert.DeserializeObject<UserContext>(context);
conObj1.AuthObject = JsonConvert.DeserializeObject<Auth>(conObj1.AuthValue);

You could move this into the class if you wanted and call it directly off the deserialized class.

public class UserContext
{
    public string AccountNo { get; set; }
    public string AuthValue { get; set; }
    public Auth AuthObject { get; private set; }

    internal UserContext Deserialize()
    {
        // Serialize the object
        this.AuthObject = JsonConvert.DeserializeObject<Auth>(this.AuthValue);

        // Return this object for a simple single-line call.
        return this;
    }
}

// Single object
UserContext conObj1 = new UserContext();
conObj1 = JsonConvert.DeserializeObject<UserContext>(context).Deserialize();

// Enumeration of object (given that this is supported in JsonConvert)
IEnumerable<UserContext> conObjs = JsonConvert.DeserializeObject<IEnumerable<UserContext>(contexts).Select(c => c.Deserialize()).ToList();

Or if you feel self hating you could go as far as doing the deserialization at the time the property is accessed (although I would avoid this at almost all costs due to the numerous issues it can cause).

public class UserContext
{
    private Auth m_auth;

    public string AccountNo { get; set; }
    public string AuthValue { get; set; }
    public Auth AuthObject
    {
        get
        {
            if (this.m_auth == null)
            {
                this.m_auth = JsonConvert.DeserializeObject<Auth>(this.AuthValue);
            }

            return this.m_auth;
        }
    }
}
2

I would suggest using two classes - one for the JSON you're actually receiving, and then one for the object model you want to use:

public class JsonUserContext
{
    public string AccountNo { get; set; }
    public string AuthValue { get; set; }
}

public class UserContext
{
    public string AccountNo { get; set; }
    public Auth AuthValue { get; set; }
}

public class Auth
{
    public string TopUpMobileNumber { get; set; }
    public string VoucherAmount { get; set; }
}

...

var jsonUserContext = JsonConvert.DeserializeObject<JsonUserContext>(json);
var authJson = jsonUserContext.AuthValue;
var userContext = new UserContext {
    AccountNo = jsonUserContext.AccountNo,
    AuthValue = JsonConvert.DeserializeObject<JsonUserContext>(authJson);
};
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • I had a similar question [posted here](https://stackoverflow.com/questions/61375112/deserialize-json-string-embedded-within-json-directly). (I had looked around; couldn't find any similar question posted before until now). Do you think there's a better way to directly parse the embedded Json string now? My question isn't a duplicate in my opinion. Currently, I'm separately parsing the embedded json string. Looking for a more direct approach. – Adithya Upadhya Apr 22 '20 at 23:47
  • @AdithyaUpadhya: No, I don't think so. – Jon Skeet Apr 23 '20 at 05:43