Динамический доступ JSON Свойство с RestSharp - PullRequest
1 голос
/ 29 января 2020

Я извлекаю данные из API, который позволяет настраивать поля, что приводит к изменению структуры ответа JSON для различных вызовов API. Я использую RestSharp / Simple JSON для десериализации JSON в объект, определенный в моем проекте. Мои пользователи могут настроить свои учетные записи так, чтобы они извлекали свои собственные настраиваемые поля, но моя проблема в том, что я не могу десериализовать новые настраиваемые поля в свой объект без добавления этого свойства в класс, перекомпиляции и развертывания изменений. У кого-нибудь есть идеи, как я мог получить доступ к этому новому настраиваемому полю, не добавляя свойство в класс и не перераспределяя его? Примеры ниже ...

определение

 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);
        }
        ...
    }

использование

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

json ответ для клиента AB C

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

json ответ для клиента XYZ

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

Моя проблема заключается в том, что, когда OIU клиента добавляется и его GradeCustomFieldName имеет значение CustomfieldOIU, я должен добавить его в определение своего класса, прежде чем они смогут использовать приложение.

Ответы [ 3 ]

1 голос
/ 29 января 2020

звучит так, будто вы просто хотите иметь возможность хранить произвольные json и десериализовать в класс. Я не могу придумать, как это сработает, если не хранить только полную строку json и анализировать ее по-своему.

Если вы хотите произвольную json, вы идете необходимо хранить его в произвольном классе контейнерного типа, таком как ExpandoObject , который является c# классом, к которому можно динамически добавлять свойства во время выполнения.

0 голосов
/ 29 января 2020

Мне нравятся простые решения. Так же, как и Simple Json ...

Когда я с ним работаю, я обычно доверяю ему только, чтобы дать мне Dictionary<string,object>. Тогда я могу или не могу использовать это для извлечения других битов данных. Это немного больше работы, но с nameof() это по крайней мере будет безопасно во время компиляции. (Кроме того, это хорошее место, чтобы также проверить ваш ввод. Вы проверяете правильно? что, если бы я мог изменить форму того, что я получаю .....

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

Скорее всего, это был бы самый чистый путь; На этом этапе не требуется ExpandoObject или JObject, что обеспечивает большую гибкость в будущем (т. Е. Более одного «класса»)

0 голосов
/ 29 января 2020

Вы можете сохранить его как key value pairs или оставить как json

Вот несколько примеров

[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();
        }
...