C#自定义实现Json字符串向对象转换:基于反射与特性映射
本文将详细介绍如何在C#环境中,通过自定义Attribute结合反射技术,将简单的JSON字符串转换为特定的C#对象实例。该方法避免了引入大型序列化库的开销,适合处理结构简单、格式固定的JSON数据。
设计思路与准备条件
目标:将形如{"key":"value", "id":123}格式的JSON字符串解析为C#类实例。
核心原理:
- 使用
[JsonField]自定义特性标记类属性,指定其对应的JSON键名。 - 利用反射获取类的公共属性及对应的特性信息。
- 通过简单的字符串分割提取
JSON中的键值对(注意:此方法仅适用于简单的扁平结构)。 - 使用泛型
Type.Parse方法进行类型转换赋值。
第一步:定义映射特性
首先需要创建一个继承自Attribute的特性类,用于标识C#属性与JSON字段名称的对应关系。
代码如下:
namespace JsonMapper
{
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = false)]
public class JsonFieldAttribute : Attribute
{
private string _Name = string.Empty;
public string Name
{
get { return _Name; }
set { _Name = value; }
}
}
}
第二步:实现核心转换器
创建JsonToInstance类,实现从JSON字符串到任意类型的转换。核心在于解析逻辑和类型匹配。
代码如下:
namespace JsonMapper
{
public class JsonToInstance
{
///
/// 将JSON字符串转换为指定类型的对象
///
public T ToInstance<T>(string json) where T : new()
{
// 1. 简单解析JSON为字典 (注意:此方法仅支持最简JSON结构)
Dictionary<string, string> dic = new Dictionary<string, string>();
// 去除首尾花括号(如有)并根据逗号分割键值对
string content = json.Trim().Trim('{', '}');
string[] fields = content.Split(',');
for (int i = 0; i < fields.Length; i++)
{
string[] keyvalue = fields[i].Split(':');
if (keyvalue.Length == 2)
{
dic.Add(Filter(keyvalue[0]), Filter(keyvalue[1]));
}
}
// 2. 获取所有公共实例属性
PropertyInfo[] properties = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);
T entity = new T();
// 3. 遍历属性并赋值
foreach (PropertyInfo property in properties)
{
object[] propertyAttrs = property.GetCustomAttributes(false);
foreach (object propertyAttr in propertyAttrs)
{
if (propertyAttr is JsonFieldAttribute jsonFieldAttribute)
{
// 查找匹配的键
foreach (KeyValuePair<string, string> item in dic)
{
if (item.Key == jsonFieldAttribute.Name)
{
Type t = property.PropertyType;
// 进行类型转换
property.SetValue(entity, ToType(t, item.Value), null);
break;
}
}
break;
}
}
}
return entity;
}
///
/// 过滤JSON字符串中的引号
///
private string Filter(string str)
{
if (!str.StartsWith("\"") || !str.EndsWith("\""))
{
return str.Trim();
}
else
{
return str.Substring(1, str.Length - 2);
}
}
///
/// 根据类型将字符串转换为对应对象
///
public object ToType(Type type, string value)
{
// 如果是字符串直接返回
if (type == typeof(string))
{
return value;
}
// 尝试查找静态Parse方法
MethodInfo parseMethod = null;
foreach (MethodInfo mi in type.GetMethods(BindingFlags.Static | BindingFlags.Public))
{
if (mi.Name == "Parse" && mi.GetParameters().Length == 1)
{
parseMethod = mi;
break;
}
}
if (parseMethod == null)
{
throw new ArgumentException($"Type: {type.Name} does not have a valid Parse method!");
}
// 调用Parse方法
return parseMethod.Invoke(null, new object[] { value });
}
}
}
第三步:定义业务模型
创建需要使用此转换器的C#类,并使用[JsonField]标记每个属性。
代码如下:
// JSON样例: { "result": 100, "response": "Hello", "id": 123, "msg": "OK." }
public class Message
{
[JsonField(Name = "result")]
public int Result { get; set; }
[JsonField(Name = "response")]
public string Response { get; set; }
[JsonField(Name = "id")]
public int Id { get; set; }
[JsonField(Name = "msg")]
public string Msg { get; set; }
}
第四步:测试与运行
在主程序中调用转换器,验证结果是否符合预期。
代码如下:
class Program
{
static void Main(string[] args)
{
JsonToInstance util = new JsonToInstance();
// 注意:输入应为标准的JSON字符串格式
string json = @"{""response"":""我是阿猫酱的小黄鸡"",""id"":21231513,""result"":100,""msg"":""OK.""}";
try
{
Message m = util.ToInstance<Message>(json);
Console.WriteLine($"ID: {m.Id}, Msg: {m.Msg}");
}
catch (Exception ex)
{
Console.WriteLine($"Error: {ex.Message}");
}
}
}
局限性与注意事项
- 解析方式简易:上述代码使用
Split(',')进行分割,这意味着它不支持嵌套JSON或数组类型的字段,也不处理JSON注释。 对于复杂的JSON结构,建议使用成熟的库如Newtonsoft.Json或System.Text.Json。 - 类型限制:目前仅支持具有静态
Parse(string)方法的类型(如int,double,DateTime等)。如果需要支持自定义复杂类型,需扩展ToType方法。 - 性能考量:由于大量使用了反射,此方法的执行效率低于原生序列化库。它更适合低频调用或轻量级场景。
以上就是C#自定义实现Json字符串向C#对象转变的详细内容,更多关于C# Json转换的资料请关注本站其它相关文章!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









