在C#中引用主要对象变量

问题描述

我有一个通过自定义JsonConverter填充的对象。我想在其中传递/共享一个主要对象属性

Weather.cs

[JsonConverter(typeof(JsonPathConverter))]
public class Weather
{
    public DateTime RequestDate { get; set; }

    [JsonProperty(PropertyName = "timezone_offset")]
    public int TimezoneOffset { get; set; }

    [JsonProperty(PropertyName = "current")]
    public Current Current { get; set; }
}

当前

[JsonConverter(typeof(JsonPathConverter))]
public class Current
{
    [JsonProperty(PropertyName = "dt")]
    public int Timestamp { get; set; }

    public string FormattedDate()
    {
        string response = string.Empty;

        // Here's where I want to access TimezoneOffset

        return response;
    }

    // More stuff...
}

JsonPathConverter

public class JsonPathConverter : JsonConverter
{
    public override object ReadJson(JsonReader reader,Type objectType,object existingValue,JsonSerializer serializer)
    {
        JObject jo = JObject.Load(reader);
        object targetobj = Activator.CreateInstance(objectType);

        foreach (PropertyInfo prop in objectType.GetProperties().Where(p => p.CanRead && p.CanWrite))
        {
            JsonPropertyAttribute att = prop.GetCustomAttributes(true)
                                            .OfType<JsonPropertyAttribute>()
                                            .FirstOrDefault();

            string jsonPath = (att != null ? att.PropertyName : prop.Name);
            JToken token = jo.SelectToken(jsonPath);

            if (token != null && token.Type != JTokenType.Null)
            {
                object value = token.ToObject(prop.PropertyType,serializer);
                prop.SetValue(targetobj,value,null);
            }
        }

        return targetobj;
    }

    public override bool CanConvert(Type objectType)
    {
        return true;
    }

    public override bool CanWrite
    {
        get { return true; }
    }

    public override void WriteJson(JsonWriter writer,object value,JsonSerializer serializer)
    {
        if (value.GetType().IsGenericType && value is IEnumerable)
        {
            JArray result = new JArray();
            IEnumerable list = value as IEnumerable;

            foreach(var obj in list)
                result.Add(GetobjectJson(obj));

            result.Writeto(writer);
        }
        else
        {
            JObject result = GetobjectJson(value);
            result.Writeto(writer);
        }
    }

    private JObject GetobjectJson(object obj)
    {
        JObject jObj = new JObject();

        if (obj != null)
        {
            PropertyInfo[] props = obj.GetType().GetProperties();

            foreach (PropertyInfo prop in props)
            {
                if (prop.PropertyType.ToString().Contains("System") || prop.PropertyType.ToString().Contains("Json"))
                    jObj.Add(char.ToLowerInvariant(prop.Name[0]) + prop.Name.Substring(1),JToken.FromObject(prop.GetValue(obj)));
                else
                    jObj.Add(char.ToLowerInvariant(prop.Name[0]) + prop.Name.Substring(1),GetobjectJson(prop.GetValue(obj)));
            }
        }

        return jObj;
    }
}

我尝试使用层次结构,但是在序列化JSON时会创建一个空的Current对象。

更新

更清楚地说,这是我如何使用此示例:

我制作了一个HttpRequest,它返回了这样的JSON:

{
    "timezone_offset": 7200,"current": {
        "dt": 1600242501,"sunrise": 1600234796,"sunset": 1600279440,"temp": 24.85,"feels_like": 26.84,"pressure": 1019,"humidity": 78,"dew_point": 20.75,"uvi": 7.42,"clouds": 2,"visibility": 10000,"wind_speed": 2.96,"wind_deg": 66,"weather": [{
            "id": 800,"main": "Clear","description": "cielo claro","icon": "01d"
        }]
    }
}

然后,我将其反序列化为Weather对象:

Weather weather = JsonConvert.DeserializeObject<Weather>(json.ToString());

由于Weather对象是Current本身的属性,因此它同时填充CurrentWeather对象。

然后,当我想返回Weather对象时,我这样做是这样的:

JObject.Parse(JsonConvert.SerializeObject(weather,Formatting.Indented,new JsonPathConverter()))

那一刻,我想在计算的FormattedDate对象中返回一个新字段Current。我之前已经做过并且可以正常工作,现在的问题是我希望它在此字段中使用父属性TimezoneOffset

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)