简体   繁体   English

有没有办法在 JSON 文件的值中获取键名

[英]Is there a way to get the key name in value of JSON file

I want to populate a property based on the name of the name of the key.我想根据键名填充属性。 Eg The AddressType for the physicalAddress would be physicalAddress.例如,physicalAddress 的 AddressType 将是physicalAddress。 Currently Im using Newtonsoft.Json.目前我正在使用 Newtonsoft.Json。 This information will be stored in a database using EntityFramework.此信息将使用 EntityFramework 存储在数据库中。

Thanks谢谢

This is an example part of the JSON file:这是 JSON 文件的示例部分:

"person": [
  {
    "physicalAddress": [
      {
        "address": "123 Street Name",
        "postCode": 1122
      }
    ],
    "postalAddress": [
      {
        "address": "123 Street Name",
        "postCode": 1122
      }
    ],
    "registeredAddress": [
      {
        "address": "123 Street Name",
        "postCode": 1122
      }
    ]
  }

This is an example part of the class:这是 class 的示例部分:

    [JsonProperty("address")]
    public string Address { get; set; }

    [JsonProperty("postCode")]
    public string PostCode { get; set; }

    public string AddressType { get; set; }

Assuming you don't want or can't change the client side, one possible approach is to create a request model that matches the format of the request body, ie假设您不想或不能更改客户端,一种可能的方法是创建一个与请求正文的格式匹配的请求 model,即

  [JsonProperty("physicalAddress")]
  public List<AddressRequestModel> PhysicalAddress { get; set; }

  [JsonProperty("postalAddress")]
  public List<AddressRequestModel> PostalAddress{ get; set; }

  [JsonProperty("registeredAddress")]
  public List<AddressRequestModel> RegisteredAddress{ get; set; }

Where AddressRequestModel would be the class containing the properties Address and PostCode .其中AddressRequestModel将是包含属性AddressPostCode的 class 。 Then when the request is received, map the request model to the model needed by your application.然后当收到请求时,map 向您的应用程序所需的 model 请求 model。 In the mapper you can assign the appropriate address type, ie在映射器中,您可以分配适当的地址类型,即


public class AddressMapper
{
   public List<AddressRequestModel> Map(RequestModel model)
   {
      var addresses = new List<AddressRequestModel>();
      model.PhysicalAddress.ForEach(address => addresses.Add(Map(address, "physicalAddress"));
      model.PostalAddress.ForEach(address => addresses.Add(Map(address, "postalAddress"));
      model.RegisteredAddress.ForEach(address => addresses.Add(Map(address, "registeredAddress"));
      return addresses;
   }

   private AddressRequestModel Map(AddressRequestModel model, string addressType) =>
   new AddressRequestModel
   {
       Address = model.Address,
       PostCode = model.PostCode,
       AddressType = addressType,
   }
}

I create a bit complex case to parse this json by JsonConverter.我创建了一个有点复杂的案例来解析这个 JsonConverter 的 json。 And it works for your requirements.它适用于您的要求。

The major function uses JProperty to dynamic get the address key name (physicalAddress, postalAddress, or other) and Children() to get sub nodes.主要的 function 使用JProperty动态获取地址键名(physicalAddress、postalAddress 或其他)和Children()获取子节点。

class Program
{

    static void Main(string[] args)
    {
         string json = @"
{""person"": [
  {
    ""physicalAddress"": [
      {
        ""address"": ""123 Street Name"",
        ""postCode"": 1122
      },
      {
        ""address"": ""456 Street Name"",
        ""postCode"": 7788
      }
    ],
    ""postalAddress"": [
      {
        ""address"": ""123 Street Name"",
        ""postCode"": 1122
      },
      {
        ""address"": ""9999 Street Name"",
        ""postCode"": 77886666
      }
    ],
    ""registeredAddress"": [
      {
        ""address"": ""123 Street Name"",
        ""postCode"": 1122
      },
      {
        ""address"": ""fwerg Street Name"",
        ""postCode"": 9999999
      }

    ]
  }
  
  ]
}
";

         Person person = JsonConvert.DeserializeObject<Person>(json, new MyTypeConverter());
     }
}

public class Person
{
    public List<AddressDetail> Addresses { get; set; }
}

public class AddressDetail
{
    public string Address { get; set; }

    public string PostCode { get; set; }

    public string AddressType { get; set; }
}

public class MyTypeConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return typeof(Person).GetTypeInfo().IsAssignableFrom(objectType.GetTypeInfo());
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        if (reader.TokenType == JsonToken.StartObject)
        {
            JObject item = JObject.Load(reader);
            if (item["person"] != null)
            {
                var pseron = new Person()
                {
                    Addresses = new List<AddressDetail>()
                };
                var largeAddressArr = item["person"].Children();
                foreach (var largeAddress in largeAddressArr)
                {
                    foreach (var keyAddress in largeAddress.Children())
                    {
                        string keyName = (keyAddress as JProperty).Name;
                        List<JToken> tokens = keyAddress.Children().ToList();
                        foreach (var address in tokens)
                        {
                            var addresses = address.ToObject<List<AddressDetail>>();
                            addresses.ForEach(x => x.AddressType = keyName);
                            pseron.Addresses.AddRange(addresses);
                        }
                    }
                }

                return pseron;
            }
        }
        return null;
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM