我上了这个课:
public class ValueInteger
{
[JsonIgnore]
public string ValueName { get; set; }
public int Value { get; set; }
[JsonProperty("timestamp")]
public UInt64 TimeStamp { get; set; }
}
给出以下实例:
var valueInt = new ValueInteger
{
ValueName = "mycounter",
Value = 7,
TimeStamp = 1010101010
}
它应该序列化为:
{ mycounter: 7, timestamp = 1010101010 }
如果可以将Value属性声明为
[JsonRedirect(titlePropertyName: nameof(ValueName))]
public int Value { get; set; }
我可能必须实现自己的ContractResolver,并研究了这篇文章:https://stackoverflow.com/a/47872645/304820 但是它取决于IValueProvider和AFAIK,没有用于重命名的INameProvider。
通常,重命名是按类而不是按实例进行的。
答案 0 :(得分:1)
我的解决方法是编写自己的Converter。转换器只是以与普通转换器相同的方式进行序列化,但是只要遇到属性上的特殊属性,都应在输出中重命名该属性。
因此,序列化C#对象将像这样:
我对此做了一个简单的实现。用法如下:
class Program
{
static void Main(string[] args)
{
var valueInt = new ValueInteger
{
ValueName = "mycounter",
Value = 7,
TimeStamp = 1010101010
};
var settings = new JsonSerializerSettings { Converters = new JsonConverter[] { new DynamicNameConverter() } };
var result = JsonConvert.SerializeObject(valueInt, settings);
Console.WriteLine(result);
Console.Read();
}
}
public class ValueInteger
{
[JsonIgnore]
public string ValueName { get; set; }
[JsonDynamicName(nameof(ValueName))]
public int Value { get; set; }
[JsonProperty("timestamp")]
public UInt64 TimeStamp { get; set; }
}
以及帮助程序类:
class DynamicNameConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
// Only use this converter for classes that contain properties with an JsonDynamicNameAttribute.
return objectType.IsClass && objectType.GetProperties().Any(prop => prop.CustomAttributes.Any(attr => attr.AttributeType == typeof(JsonDynamicNameAttribute)));
}
public override bool CanRead => false;
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
// We do not support deserialization.
throw new NotImplementedException();
}
public override bool CanWrite => true;
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
var token = JToken.FromObject(value);
if (token.Type != JTokenType.Object)
{
// We should never reach this point because CanConvert() only allows objects with JsonPropertyDynamicNameAttribute to pass through.
throw new Exception("Token to be serialized was unexpectedly not an object.");
}
JObject o = (JObject)token;
var propertiesWithDynamicNameAttribute = value.GetType().GetProperties().Where(
prop => prop.CustomAttributes.Any(attr => attr.AttributeType == typeof(JsonDynamicNameAttribute))
);
foreach (var property in propertiesWithDynamicNameAttribute)
{
var dynamicAttributeData = property.CustomAttributes.FirstOrDefault(attr => attr.AttributeType == typeof(JsonDynamicNameAttribute));
// Determine what we should rename the property from and to.
var currentName = property.Name;
var propertyNameContainingNewName = (string)dynamicAttributeData.ConstructorArguments[0].Value;
var newName = (string)value.GetType().GetProperty(propertyNameContainingNewName).GetValue(value);
// Perform the renaming in the JSON object.
var currentJsonPropertyValue = o[currentName];
var newJsonProperty = new JProperty(newName, currentJsonPropertyValue);
currentJsonPropertyValue.Parent.Replace(newJsonProperty);
}
token.WriteTo(writer);
}
}
[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)]
class JsonDynamicNameAttribute : Attribute
{
public string ObjectPropertyName { get; }
public JsonDynamicNameAttribute(string objectPropertyName)
{
ObjectPropertyName = objectPropertyName;
}
}
请注意,DynamicNameConverter
中可能会包含很多错误处理,但是为了便于阅读和理解,我省略了它。