我有下面的模型课,
using System.ComponentModel.DataAnnotations;
using System.Text.Json.Serialization;
public class FormField
{
[Required]
[JsonPropertyName("STD_USERTYPEID")]
public string UserTypeId { get; set; }
[Required]
[JsonPropertyName("STD_OFFICETYPEID")]
public string OfficeTypeId { get; set; }
}我有一些场景,其中STD_OFFICETYPEID可能以LegacyOFFICETYPEID或OfficeID的形式出现。有什么方法可以动态地生成JsonPropertyName吗?我正在使用System.Text.Json NuGet软件包。
请注意,此示例已简化。在我的生产代码中,可能有20-25个混凝土特性。所有这些属性都可以映射到5-10个不同的JsonPropertyNames。
发布于 2022-09-05 20:10:40
我会告诉你我怎么做的:源生成器。
首先,我会注入一个新属性JsonPropertyNames(params string[] alternativeNames),然后用它来修饰我的类,给出可能的字段名的完整列表。
然后,我将让源生成器生成第二个类与我的原始类匹配属性,包括使用JsonPropertyNames提供的每个替代名称的属性。这是您要将Json读入的类,您的所有属性都将在其中一个属性中读取。
然后,生成器将添加所有必要的AutoMapper映射代码,以便从我生成的类型复制到原始类型,以及一个助手类,它将读入生成的类型并调用AutoMapper来为您返回类。
因此,从调用方来说,您只需要调用一个函数就可以得到您的类型,而忽略了幕后的所有细节。
发布于 2022-09-06 22:47:31
如果您准备好使用swith Newtonsoft.Json,可以尝试以下代码
var json="{\"STD_USERTYPEID\":\"userId\",\"LegacyOFFICETYPEID\":\"officeId\"}";
FormField formField = DeserializeObj<FormField>(json);
public class FormField
{
[JsonProperty("STD_USERTYPEID")]
public string UserTypeId { get; set; }
[JsonPropertyNames(new string[] {"STD_OFFICETYPEID", "LegacyOFFICETYPEID" })]
public string OfficeTypeId { get; set; }
}
public T DeserializeObj<T>(string json) where T:new()
{
var jsonObj = JObject.FromObject(new T());
var attrs = GetAttrs<T>();
var jsonParsed = JObject.Parse(json);
foreach (var prop in jsonParsed.Properties())
{
var propName=prop.Name;
var attr=attrs.Where(a=>a.AttributeNames.Contains(propName)).FirstOrDefault();
if(attr!=null) jsonObj[attr.PropertyName]=prop.Value;
else jsonObj[propName]=prop.Value;
}
return jsonObj.ToObject<T>();
}
public static List<PropertyAttributes> GetAttrs<T>() where T: new()
{
var source= new T();
var attrs = new List<PropertyAttributes>();
foreach (PropertyInfo prop in source.GetType().GetProperties())
{
var attribute = prop.GetCustomAttribute<JsonPropertyNamesAttribute>();
if (attribute != null)
{
attrs.Add(new PropertyAttributes { PropertyName = prop.Name, AttributeNames = attribute.Names });
}
}
if (attrs.Count > 0) return attrs;
return null;
}
public class PropertyAttributes
{
public string PropertyName { get; set; }
public string[] AttributeNames { get; set; }
}
[AttributeUsage(AttributeTargets.All)]
public class JsonPropertyNamesAttribute : Attribute
{
private string[] names;
public JsonPropertyNamesAttribute(string[] names)
{
this.names = names;
}
public virtual string[] Names
{
get { return names; }
}
}https://stackoverflow.com/questions/73613625
复制相似问题