首页 > 解决方案 > 编译器创建匿名类型:易破坏的行为

问题描述

我有一些客户端 HTTP RESTfull 代码,这取决于 .net 编译器生成的匿名类型提供的舒适度。

匿名类型 example0 :

string prop_1 = "strValue1"; int prop_2 = 5; new { prop1 = prop_1, prop2 = prop_2};

匿名类型示例 1:

new { prop1 = "strValue1", prop2 = 5};

匿名类型 example2(也有效):

string prop1 = "strValue1"; int prop2 = 5; new { prop1, prop2};

这里的问题是,编译器生成的匿名类型属性的名称通常很重要,不能重命名。特别是如果用户主动为匿名类型声明了一个属性名称,它可能表明该名称实际上很重要——即使在程序集之外——

Dotfuscator 社区目前默认重命名匿名类型的属性。

其中一个有问题的领域是用于序列化和网络传输的 JSON 对象的“临时”构建。请参阅下面的代码。

这是一些代码,我在其中手动组装了用于 WebAPI 查询的 HTTP 消息内容。请求的正确性取决于确切的属性名称。匿名类型用于不必为每种类型的 HTTP WebAPI 查询再次声明 new -newer 来使用 - 类型。名称 username、password 和 request_token 在应用程序之外很重要(对于 API 服务器)

string baseUrl = BASE_Address + BASE_Path + VALIDATE_REQUEST_TOKEN_W_LOGIN_Path;
var query = new Dictionary<string, string>();
query.Add(API_KEY_Key, _settings.ApiKey);
string requestUri = QueryHelpers.AddQueryString(baseUrl, query);
var jsonObj = new { username = username, password = password, request_token = requestToken };
string json = JsonConvert.SerializeObject(jsonObj);
var content = new StringContent(json, encoding: Encoding.UTF8, mediaType: "application/json");

预期行为:如果 Dotfuscator 无法确定重命名匿名属性是安全的,则不应重命名它。

考虑:

  1. 如果用户主动命名了匿名类型属性,那它一定是可疑的。请注意,使用 example0 而不是较短的 example2(见上文)的唯一原因是为了防止在 Visual Studio 中重命名类型。使用 example0 即使您重命名变量 prop_1 或 prop_2 它也不会破坏匿名类型名,因此不会破坏生成的 Json 对象

  2. 如果方法或任何调用的子方法使用序列化而不是重命名属性肯定会破坏代码。(因为序列化 Json 中的类型名将取决于原始属性名称,因为没有用户声明的用于序列化命名的属性)

现在的问题是:您能否向我推荐一些保留我当前代码但确保 Dotfuscator 不会重命名方法/匿名类型中的任何内容的属性或技巧?

标签: dotfuscator

解决方案


注意:我作为 Dotfuscator 开发人员的员工以专业身份在这里回答

自 5.34 版以来,Dotfuscator 社区已包含用于从生成的匿名类型中排除属性的默认参考规则。(您可以从这里下载最新版本的 Dotfuscator 社区)。或者,您可以手动定义规则,即:

.*AnonymousType.*从包含自定义属性的命名类型中排除所有属性System.Runtime.CompilerServices.CompilerGeneratedAttribute

<type name=".*AnonymousType.*" regex="true" excludetype="false">
    <customattribute name="System\.Runtime\.CompilerServices\.CompilerGeneratedAttribute" regex="true" />
    <propertymember name="*" regex="true" />
</type>

推荐阅读