需求:在使用SpecFlow时,我希望能对目标对象所关联的对象属性进行验证,但SpecFlow(Version 1.9.0)无法实现。如图中红框,可以对专户所属的金融机构的名称进行验证。

反编译步骤

  1. 利用ildasm(.net自带)反编译 TechTalk.SpecFlow.dll 生成IL中间代码 一般会生成 *.il 和*.res 一些其它资源文件 *.resources;
  2. 然后用记事本修改IL文件;
  3. 然后用ilasm编译中间代码,生成新的 TechTalk.SpecFlow.dll 文件;
  4. 删除签名。

  详细步骤见参考文献[1]

修改前后代码对比

第一处修改

TechTalk.SpecFlow.Assist.TEHelpers 类的 IsPropertyMatchingToColumnName 方法,带“.”的列名不验证是否存在对应的属性。

// 修改前的源代码1 internal static bool IsPropertyMatchingToColumnName(PropertyInfo property, string columnName)
2 {
3     return property.Name.MatchesThisColumnName(columnName);
4 }

 // 修改前的中间语言 1 .method assembly hidebysig static bool  IsPropertyMatchingToColumnName(class [mscorlib]System.Reflection.PropertyInfo 'property',
 2                                                                        string columnName) cil managed
 3 {
 4   // Code size       13 (0xd)
 5   .maxstack  8
 6   IL_0000:  ldarg.0
 7   IL_0001:  callvirt   instance string [mscorlib]System.Reflection.MemberInfo::get_Name()
 8   IL_0006:  ldarg.1
 9   IL_0007:  call       bool TechTalk.SpecFlow.Assist.TEHelpers::MatchesThisColumnName(string,
10                                                                                       string)
11   IL_000c:  ret
12 } // end of method TEHelpers::IsPropertyMatchingToColumnName

// 修改后的源代码1 internal static bool IsPropertyMatchingToColumnName(PropertyInfo property, string columnName)
2 {
3     return ((columnName.IndexOf('.') > -1) || property.Name.MatchesThisColumnName(columnName));
4 }

 // 修改后的中间语言 1 .method assembly hidebysig static bool  IsPropertyMatchingToColumnName(class [mscorlib]System.Reflection.PropertyInfo 'property',
 2                                                                        string columnName) cil managed
 3 {
 4   // Code size       40 (0x28)
 5   .maxstack  2
 6   .locals init (bool V_0,
 7            bool V_1)
 8   IL_0000:  nop
 9   IL_0001:  ldarg.1
10   IL_0002:  ldc.i4.s   46
11   IL_0004:  callvirt   instance int32 [mscorlib]System.String::IndexOf(char)
12   IL_0009:  ldc.i4.m1
13   IL_000a:  cgt
14   IL_000c:  ldc.i4.0
15   IL_000d:  ceq
16   IL_000f:  stloc.1
17   IL_0010:  ldloc.1
18   IL_0011:  brtrue.s   IL_0017
19   IL_0013:  ldc.i4.1
20   IL_0014:  stloc.0
21   IL_0015:  br.s       IL_0026
22   IL_0017:  ldarg.0
23   IL_0018:  callvirt   instance string [mscorlib]System.Reflection.MemberInfo::get_Name()
24   IL_001d:  ldarg.1
25   IL_001e:  call       bool TechTalk.SpecFlow.Assist.TEHelpers::MatchesThisColumnName(string,
26                                                                                       string)
27   IL_0023:  stloc.0
28   IL_0024:  br.s       IL_0026
29   IL_0026:  ldloc.0
30   IL_0027:  ret
31 } // end of method TEHelpers::IsPropertyMatchingToColumnName

第二处修改

TechTalk.SpecFlow.Assist.PropertyExtensionMethods 类的 GetPropertyValue 方法,将属性名根据“.”分割后,循环获取关联对线的属性值。

// 修改前的源代码1 public static object GetPropertyValue(this object @object, string propertyName)
2 {
3     return GetThePropertyOnThisObject(@object, propertyName).GetValue(@object, null);
4 }

 // 修改前的中间语言 1 .method public hidebysig static object  GetPropertyValue(object 'object',
 2                                                          string propertyName) cil managed
 3 {
 4   .custom instance void [System.Core]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = ( 01 00 00 00 )
 5   // Code size       17 (0x11)
 6   .maxstack  3
 7   .locals init (class [mscorlib]System.Reflection.PropertyInfo V_0)
 8   IL_0000:  ldarg.0
 9   IL_0001:  ldarg.1
10   IL_0002:  call       class [mscorlib]System.Reflection.PropertyInfo TechTalk.SpecFlow.Assist.PropertyExtensionMethods::GetThePropertyOnThisObject(object,
11                                                                                                                                                     string)
12   IL_0007:  stloc.0
13   IL_0008:  ldloc.0
14   IL_0009:  ldarg.0
15   IL_000a:  ldnull
16   IL_000b:  callvirt   instance object [mscorlib]System.Reflection.PropertyInfo::GetValue(object,
17                                                                                           object[])
18   IL_0010:  ret
19 } // end of method PropertyExtensionMethods::GetPropertyValue

// 修改后的源代码1 public static object GetPropertyValue(this object @object, string propertyName)
2 {
3     foreach (string str in propertyName.Split(new char[] { '.' }, StringSplitOptions.RemoveEmptyEntries))
4     {
5         @object = GetThePropertyOnThisObject(@object, str).GetValue(@object, null);
6     }
7     return @object;
8 }

 // 修改后的中间语言 1 .method public hidebysig static object  GetPropertyValue(object 'object',
 2                                                          string propertyName) cil managed
 3 {
 4   .custom instance void [System.Core]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = ( 01 00 00 00 )
 5   // Code size       64 (0x40)
 6   .maxstack  4
 7   .locals init (string[] V_0,
 8            string V_1,
 9            char[] V_2,
10            string[] V_3,
11            int32 V_4)
12   IL_0000:  ldarg.1
13   IL_0001:  ldc.i4.1
14   IL_0002:  newarr     [mscorlib_6]System.Char
15   IL_0007:  stloc.2
16   IL_0008:  ldloc.2
17   IL_0009:  ldc.i4.0
18   IL_000a:  ldc.i4.s   46
19   IL_000c:  stelem.i2
20   IL_000d:  ldloc.2
21   IL_000e:  ldc.i4.1
22   IL_000f:  callvirt   instance string[] [mscorlib_6]System.String::Split(char[],
23                                                                           valuetype [mscorlib_6]System.StringSplitOptions)
24   IL_0014:  stloc.0
25   IL_0015:  ldloc.0
26   IL_0016:  stloc.3
27   IL_0017:  ldc.i4.0
28   IL_0018:  stloc.s    V_4
29   IL_001a:  br.s       IL_0037
30   IL_001c:  ldloc.3
31   IL_001d:  ldloc.s    V_4
32   IL_001f:  ldelem.ref
33   IL_0020:  stloc.1
34   IL_0021:  ldarg.0
35   IL_0022:  ldloc.1
36   IL_0023:  call       class [mscorlib]System.Reflection.PropertyInfo TechTalk.SpecFlow.Assist.PropertyExtensionMethods::GetThePropertyOnThisObject(object,
37                                                                                                                                                     string)
38   IL_0028:  ldarg.0
39   IL_0029:  ldnull
40   IL_002a:  callvirt   instance object [mscorlib_6]System.Reflection.PropertyInfo::GetValue(object,
41                                                                                             object[])
42   IL_002f:  starg.s    'object'
43   IL_0031:  ldloc.s    V_4
44   IL_0033:  ldc.i4.1
45   IL_0034:  add
46   IL_0035:  stloc.s    V_4
47   IL_0037:  ldloc.s    V_4
48   IL_0039:  ldloc.3
49   IL_003a:  ldlen
50   IL_003b:  conv.i4
51   IL_003c:  blt.s      IL_001c
52   IL_003e:  ldarg.0
53   IL_003f:  ret
54 } // end of method PropertyExtensionMethods::GetPropertyValue

参考文献

[1] 编辑IL文件,修改DLL文件

[2] IL指令详细

转载于:https://www.cnblogs.com/tuty/p/5716882.html

通过反编译让SpecFlow支持多层属性值的验证相关推荐

  1. java反编译,eclipse支持插件

    http://java.decompiler.free.fr/?q=jdeclipse 按照说明 在eclipse更新插件就可以. 这样 在一些 闭源的jar文件,你也可以看到 大致的源码.(公司 知 ...

  2. 弥补Reflector反编译对中文支持的不足

    Reflector是我目前用的最多的反编译工具,他可能不时最好的,但以它的更新速度,我相信他会成为最好的哦~~     国外的软件,对中文支持还是有问题,虽然我们都Unicode了,可是老外还是不一定 ...

  3. [转]一款可以反编译jar包的java反编译工具-JD-GUI(绿色软件)

    [转]一款可以反编译jar包的java反编译工具-JD-GUI(绿色软件) 文章分类:Java编程 该软件无需安装,界面清爽. 转自:http://www.devdoc.org/index.php/a ...

  4. java反编译工具_ReverseTool逆向工具集合

    反向工具 逆向工具集合 真棒骇客 Java和Jar(Android) jd-gui jar包浏览工具,对应的IDE插件,JD-Eclipse / JD-IntelliJ Luyten一个用于Procy ...

  5. .net 编译、反编译、查壳、脱壳、反混淆工具

    https://tools.pediy.com/win/dotnet.htm .NET Reflector & Reflexil 反编译工具,支持修改il代码 ILSpy 反编译工具,支持调试 ...

  6. 推荐一款非常好用的java反编译工具

    用c++写成,可反编译class文件,支持jar包级的反编译,可将整个jar包直接保存为*.src.zip源代码包,反编译迅速,错误率极少,详细的看下面 下载地址:http://java.decomp ...

  7. 【教程】jadx反编译工具的安装

    文章目录 一.什么是jadx 二.安装 一.什么是jadx JADX是一款优秀的Android反编译工具,支持命令行和图形化界面,能为我们省下大量的反编译时间. 二.安装 前提首先需要安装java的j ...

  8. 一键反编译安卓apk文件

    说明 自己集成了市面上几个常用android反编译工具.方便大家研究app的代码,仅用于学习目的. 使用方式: 使用 一键反编译: apkfull <apk_file> <app_n ...

  9. java 反编译软件

    1.小颖反编译软件. 最新的Java反编译工具,支持目录级的反编译,也支持双击.class文件就可查看源文件. 2.『XJad』简要介绍 =============================== ...

最新文章

  1. python自动化上传图片_接口自动化之Python3_Requests之上传头像
  2. Webview--如何让加载进来的页面自适应手机屏幕分辨率居中显示
  3. angular模态框位置_宽带双波束双模态OAM反射阵天线
  4. 第五篇:Spring Boot整合filter
  5. 力扣383.赎金信(JavaScript)
  6. SpringCloud工作笔记040---zuul网关集合springsecurity_JWT 颁发token_但是Authorization无法传递到response的header中
  7. 不仅限于智慧城市 低功耗广域网络也在改变农业生产方式
  8. selenium:解决页面元素display:none的方法
  9. 华硕ASUS acrh17 PandoraBox固件
  10. x230键盘排线怎么拆_【HQP教程】记一次X230更换X220键盘
  11. java字节码查看器_jclasslib 64位
  12. 安装配置管理 之 NVIDIA nForce Linux Drivers 集成声网卡和声卡的安装说明
  13. 监听php队列,执行一个队列监听
  14. 三年级计算机之父童年教学设计,三年级语文计算机之父的童年故事课文教学设计...
  15. 怎么上传云班课的计算机作业,云班课怎么交作业_云班课作业提交教程_3DM手游...
  16. 解决nested exception is java.lang.IllegalArgumentException: No converter found for return value of typ
  17. Arduino Uno 使用MAX7219驱动单个8*8点阵LED模块
  18. 201671010412 郭佳 实验四附加实验
  19. 51单片机通过ESP8266模块与手机进行通讯
  20. Java后端通过代理服务器请求网络资源

热门文章

  1. openwrt nas_NAS里整个软路由
  2. java wado_dcm4che,WADO相关
  3. linux 文件乱码_RedHatlinux系统虚机启动后/etc/fstab中的文件系统未能挂载上
  4. mysql8.0连接错误_MySql 8.0连接失败
  5. oracle游标缓存,【oracle】游标——数据的缓存区
  6. linux 查看usb端口_linux开发:Linux下查看端口占用
  7. mysql merge事务_mysql菜鸟手迹11--mysql存储引擎之Merge
  8. datetime 索引_超全的数据库建表/SQL/索引规范,适合贴在工位上!
  9. easyui中动态使datebox、combobox为只读状态
  10. 浅谈过程和结果的关系