1

I am pulling data from an API that allows for custom fields which results in the JSON response changing structure for different API calls. I am using RestSharp/SimpleJSON to deserialize the JSON into an object defined in my project. My users are able to configure their accounts to pull their own custom fields, but my issue is that I'm not able to deserialize new custom fields into my object without adding that property to the class, recompiling, and deploying the changes. Does anyone have an idea how I could access this new custom field without having to add the property to the class and redeploying? Examples below...

definition

 public class UserFields
    {
        public string Username {get;set;}
        public string FirstName {get;set;}
        public string LastName {get;set;}
        public string GradeCustomFieldName {get;set;}
        public string CustomfieldABC {get;set;} //user ABC's custom field for "grade"
        public string CustomfieldXYZ {get;set;} //user XYZ's custom field for "grade"
        public string CustomfieldLMNO {get;set;} //user LMNO's custom field for "grade"
        public string CustomfieldASDF {get;set;} //user ASDF's custom field for "grade"
        public string UserGrade 
        {
             string grade = this.GetType().GetProperty(this.gradeCustomFieldName).GetValue(this);
        }
        ...
    }

usage

UserFields userFields = SimpleJson.DeserializeObject<UserFields>(jsonResponse);
string userGrade = userFields.UserGrade;

json response for client ABC

{
"Username": "bobslydale",
"FirstName": "bob",
"LastName":  "slydale",
"GradeCustomFieldName": "CustomfieldABC",
"CustomfieldABC": "A"
}

json response for client XYZ

{
"Username": "bobslydale",
"FirstName": "bob",
"LastName":  "slydale",
"GradeCustomFieldName": "CustomfieldXYZ",
"CustomfieldXYZ": "C"
}

My issue is that when client OIU is added and their GradeCustomFieldName is CustomfieldOIU, I have to add it to my class definition before they can use the app.

1
  • Why can't you just keep it as JSON? Store it as JSON or store it as key value pairs, then serialize it into json and send it to the client. Commented Jan 28, 2020 at 22:41

3 Answers 3

1

it sounds like you just want to be able to store arbitrary json and deserialize to a class. I can't really think of a way this would work out without having just a full-on json string stored and parsing it in your own custom way.

If you want arbitrary json you are going to need to store it in an arbitrary container type class like ExpandoObject which is a c# class you can dynamically add properties to at runtime.

Sign up to request clarification or add additional context in comments.

Comments

0

YOu can store it as key value pairs or keep it as json

Here are some examples

[HttpGet]
        public JToken Get()
        {
            using (var conn = this.generalConfig.NewDbConnection)//just example db connection
            {
                var jObj = new JObject();
                foreach (var setting in conn.GetAll<AppSetting>())
                {
                    jObj[setting.AppSettingKey] = setting.AppSettingValue;
                }
                return jObj; //I'm returning the object to the client without restarting the app.
            }
        }

        [HttpPut]
        public JToken Put([FromBody] JToken settings)
        {
            using (var conn = this.generalConfig.NewDbConnection) //example db
            {
                var currSettings = conn.GetAll<AppSetting>();
                foreach (JProperty setting in settings)
                {
                    var currSetting = currSettings.FirstOrDefault(c => c.AppSettingKey == setting.Name);
                    if (currSetting == null)
                    {
                        conn.Insert(new AppSetting { AppSettingKey = setting.Name, AppSettingValue = Convert.ToString(setting.Value) });
                    }
                    else
                    {
                        currSetting.AppSettingValue = Convert.ToString(setting.Value);
                        conn.Update(currSetting);
                    }
                    // adding or updating key value pair that is stored in db
                }
            }
            return Get();
        }

Comments

0

I like simple solutions. So does SimpleJson...

When I work with it, I usually only trust it to give me a Dictionary<string,object>. Then I may or may not use this to pull other bits of data in. it's a tiny bit more work but with nameof() it will at least be compile time safe. (Besides, it's a good spot to also validate your input. You are validating right? ;) But if you used Dictionary<string,string> then you can just put the indirection in how you call your new UserFields.

Failing that, if I could change the shape of what I get in.....

public Dictionary<string,string> CustomFields {get;set;} = new Dictionary<string,string>();

Would likely be cleanest way to go; No ExpandoObject or JObject needed at that point and allows more future flexibility (i.e. more than one 'grade')

Comments

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.