以前,.NET 使用 System.DirectoryServices.Protocols.BerConverter 分析通过网络收到的 System.DirectoryServices.Protocols.DirectoryControl 对象,并生成发送的 System.DirectoryServices.Protocols.DirectoryControl 字节数组。 System.DirectoryServices.Protocols.BerConverter 使用了特定于 OS 的 BER 分析功能。 此分析功能现在在托管代码中实现。
以前的行为
由于使用 System.DirectoryServices.Protocols.BerConverter,System.DirectoryServices.Protocols.DirectoryControl 对象的分析相当松散:
- 未检查每个值的 ASN.1 标记。
 - 已分析的 DirectoryControl 末尾之后的尾随数据被忽略,就像 ASN.1 SEQUENCE 中的尾随数据一样。
 - 在 Linux 上,OCTET STRING 长度如果超出了其父序列的末尾,就会返回父序列之外的数据。
 - 在早期版本的 Windows 上,零长度的 OCTET STRING 返回 
null而不是空字符串。 - 将 System.DirectoryServices.Protocols.DirectoryControl 的内容作为 UTF8 编码的字符串读取时,无效的 UTF8 序列不会引发异常。
 - 将无效的 UTF8 字符串传递给 VlvRequestControl的构造函数时,不会引发异常。
 
虽然不是中断性变更,但 Windows 始终使用四字节长度对 ASN.1 标记进行编码,而 Linux 仅根据需要使用任意数量的字节作为标记长度。 这两种表示形式都有效,但平台之间的这种行为差异现已消失;Linux 行为现在也显示在 Windows 上。
新行为
DirectoryControl 分析更为严格,现在跨平台和版本保持一致:
- 现在检查 ASN.1 标记。
 - 不再允许尾随数据。
 - 现在检查 
OCTET STRING和SEQUENCE的长度。 - 零长度的 
OCTET STRING现在始终返回空字符串。 - 如果服务器发送无效的 UTF8 字节序列,则 System.DirectoryServices.Protocols.DirectoryControl 分析逻辑现在引发异常,而不是以无提示方式用已知值替换无效字符。
 
调用 VlvRequestControl 构造函数时,我们还会更彻底地验证错误。 传递无法编码为 UTF8 值的字符串现在会引发 EncoderFallbackException。
引入的版本
.NET 10 预览版 1
重大变更的类型
此更改为行为更改。
更改原因
此更改针对 RFC 和规范符合性进行了。 在 MS-ADTS 的各种 RFC 和部分中,controlValue 被指定为 ASN.1 结构的 BER 编码,其措辞类似于以下内容(RFC2891,第 1.2 节):
controlType 设置为“1.2.840.113556.1.4.474”。 严重性为 FALSE(可能不存在)。 controlValue 是 OCTET STRING,其值是以下 SEQUENCE 值的 BER 编码:
这排除了后置数据。 它还将排除 ASN.1 结构中不同 ASN.1 标记的 BER 编码,以及无效的 BER 编码(例如,比所在 SEQUENCE 更长的 OCTET STRING)。
对于 VlvRequestControl 构造函数,提前抛出异常意味着用户可以信赖,只有他们明确指定的值会被发送到服务器。 在任何情况下,它们都不会意外地将 EF BF BD 发送到服务器,因为它们传递的字符串无法编码为有效 UTF8 字节。
建议的操作
服务器应符合 RFC 和规范。 在调用 EncoderFallbackException 构造函数时,请确保对 VlvRequestControl 进行处理。