【问题标题】:Dynamically Access JSON Property with RestSharp使用 RestSharp 动态访问 JSON 属性
【发布时间】:2020-01-29 08:14:46
【问题描述】:

我正在从允许自定义字段的 API 中提取数据,这会导致不同 API 调用的 JSON 响应结构发生变化。我正在使用 RestSharp/SimpleJSON 将 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;

客户端 ABC 的 json 响应

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

客户端 XYZ 的 json 响应

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

我的问题是,当添加客户端 OIU 并且他们的 GradeCustomFieldName 为 CustomfieldOIU 时,我必须将其添加到我的类定义中,然后他们才能使用该应用程序。

【问题讨论】:

  • 为什么不能把它保存为 JSON?存储为JSON或存储为键值对,然后序列化成json发送给客户端。

标签: c# json restsharp simplejson


【解决方案1】:

听起来您只是希望能够存储任意 json 并反序列化为一个类。如果不存储一个完整的 json 字符串并以您自己的自定义方式解析它,我真的想不出一种方法。

如果您想要任意 json,您需要将其存储在任意容器类型类中,例如 ExpandoObject,这是一个可以在运行时动态添加属性的 c# 类。

【讨论】:

    【解决方案2】:

    您可以将其存储为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();
            }
    

    【讨论】:

      【解决方案3】:

      我喜欢简单的解决方案。 SimpleJson 也是如此......

      当我使用它时,我通常只相信它会给我一个Dictionary&lt;string,object&gt;。 然后我可能会也可能不会使用它来提取其他数据位。这需要做更多的工作,但使用nameof() 至少在编译时是安全的。 (此外,它也是验证您的输入的好地方。您正在验证正确吗?;)但是如果您使用了Dictionary&lt;string,string&gt;,那么您可以将间接设置为您调用new UserFields 的方式。

      如果我能改变我进入的形状......

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

      可能是最干净的方法;此时不需要 ExpandoObject 或 JObject 并允许更多的未来灵活性(即多个“等级”)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-12-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-01-18
        • 1970-01-01
        • 2017-09-30
        相关资源
        最近更新 更多