Ссылка на главную объектную переменную в C#

#c# #json.net #hierarchy

#c# #json.net #иерархия

Вопрос:

У меня есть объект, который заполняется через пользовательский 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 amp;amp; 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 amp;amp; 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 amp;amp; 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 создается пустой текущий объект.

Обновить

Чтобы было более понятно, вот пример того, как я использую это:

Я создаю 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 объекты, поскольку Current object является свойством Weather самого себя.

Затем, когда я хочу вернуть Weather объект, я делаю это следующим образом:

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

В этот момент я хочу вернуть новое поле FormattedDate в Current объекте, которое вычисляется. Я делал это раньше, и это работает, проблема сейчас в том, что я хочу, чтобы он использовал родительское свойство TimezoneOffset в этом поле.

Комментарии:

1. Почему и как вы хотите «получить доступ» к timezoneOffset?

2. @Fildor ну, я хочу вернуть строку с отформатированной датой. Поскольку это может быть дата из любого места, я должен применить смещение, чтобы получить правильное datetime.

3. @Sinatr Я не уверен, что ты мне говоришь.

4. У @JohnG Weather есть Current свойство объекта, которое я хочу использовать Weather.TimezoneOffset внутри этого Current свойства.

5. Вы добавляете метод в DTO и, согласно редактированию, это должно быть свойство . Просто десериализуйте Weather , присвоите новое значение новому свойству и сериализуйте. Вам не нужны ссылки или преобразователи.