如何通过反射从NameValueCollection获取带特性的RspServer类属性值
利用反射将NameValueCollection映射到RspServer类属性
这问题我之前做接口对接时碰到过类似场景,核心就是通过反射结合特性来完成数据的自动映射,不用手动一个个赋值。咱们一步步来实现:
实现思路
- 先拿到
RspServer类的所有公共属性 - 遍历每个属性,读取它的
Description特性值(这个值就是NameValueCollection里对应的键) - 用特性值作为键,从
NameValueCollection中取出对应的值 - 通过反射把值设置到
RspServer的实例属性上
完整代码实现
首先是你提供的RspServer类(我调整了格式让它更规范):
public class RspServer { private string _receiptNum, _respCode; [Description("Receipt Number")] public string ReceiptNum { get { return _receiptNum; } set { _receiptNum = value; } } [Description("Response Code")] public string RespCode { get { return _respCode; } set { _respCode = value; } } }
接下来是核心的映射方法,我把它封装成静态工具类,方便后续复用:
using System.Collections.Specialized; using System.ComponentModel; using System.Reflection; public static class ReflectionMapper { public static RspServer MapToRspServer(NameValueCollection nvc) { if (nvc == null) throw new ArgumentNullException(nameof(nvc)); var serverInstance = new RspServer(); // 获取RspServer类的所有公共实例属性 PropertyInfo[] properties = typeof(RspServer).GetProperties(BindingFlags.Public | BindingFlags.Instance); foreach (var prop in properties) { // 尝试获取当前属性的Description特性 var descriptionAttr = prop.GetCustomAttribute<DescriptionAttribute>(); if (descriptionAttr == null) continue; // 没有特性的属性直接跳过 // 用特性描述值作为键,从NameValueCollection中取值 string value = nvc[descriptionAttr.Description]; if (string.IsNullOrEmpty(value)) continue; // 没找到对应值也跳过 // 把值设置到RspServer实例的对应属性上 prop.SetValue(serverInstance, value); } return serverInstance; } }
使用示例
你可以这样调用这个工具方法:
// 模拟服务器返回的NameValueCollection数据 var serverResponse = new NameValueCollection { {"Receipt Number", "RC123456"}, {"Response Code", "0000"} }; // 完成映射得到RspServer实例 RspServer rspServer = ReflectionMapper.MapToRspServer(serverResponse); // 验证结果 Console.WriteLine($"ReceiptNum: {rspServer.ReceiptNum}"); // 输出 RC123456 Console.WriteLine($"RespCode: {rspServer.RespCode}"); // 输出 0000
额外补充
- 如果你的
NameValueCollection键和特性值存在大小写差异,可以用nvc.Get(descriptionAttr.Description)来取值(Get方法默认不区分大小写) - 如果属性类型不是字符串,还需要添加类型转换逻辑,比如把字符串转成int、DateTime等,这个可以根据实际需求扩展
- 代码里已经做了空值判断,避免出现空引用异常
内容的提问来源于stack exchange,提问作者JosephCenk
相关产品推荐
相关产品推荐

