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

时间:2020-08-20 02:13:06

标签: c# json entity-framework json.net

我想根据键名的名称填充属性。例如。 physicalAddress的AddressType将为physicalAddress。目前,我正在使用Newtonsoft.Json。此信息将使用EntityFramework存储在数据库中。

谢谢

这是JSON文件的示例部分:

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

这是该类的示例部分:

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

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

    public string AddressType { get; set; }

2 个答案:

答案 0 :(得分:0)

假设您不希望或无法更改客户端,一种可能的方法是创建一个与请求主体的格式匹配的请求模型,即

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

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

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

其中AddressRequestModel是包含属性AddressPostCode的类。然后,在收到请求时,将请求模型映射到应用程序所需的模型。在映射器中,您可以分配适当的地址类型,即


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,
   }
}

答案 1 :(得分:0)

我创建了一个复杂的案例,以通过JsonConverter解析此json。它可以满足您的要求。

主要功能使用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();
    }
}