简体   繁体   English

什么时候检查 xmlns?

[英]When do xmlns get checked?

I am using the C# XmlSerializer to deserialize some XML that has an xmlns declaration in one part of it (note that I truncated the CipherValue to fit this post):我正在使用 C# XmlSerializer 反序列化一些 XML 在其中的一部分中具有 xmlns 声明(请注意,我截断了 CipherValue 以适应这篇文章):

<EncryptedData
  Id="ZbjUzHbD37LI2DEuiEGX6A7PSnQ+19dutLPiDxZqnFY=3NLz2QA5KCiXVlJSXejhDQ=="
  Type="http://www.w3.org/2001/04/xmlenc#Element" xmlns="http://www.w3.org/2001/04/xmlenc#"
  length="44">
  <EncryptionMethod
    Algorithm="http://www.w3.org/2001/04/xmlenc#aes256-cbc" />
  <CipherData>
    <CipherValue>3NLz2QA5KCiXVlJSXejhDZYYa9sLbv/w42....+PsLMCfRFN//StgbYoRqno3WQ==</CipherValue>
  </CipherData>
</EncryptedData>

With this XML loaded into Visual Studio, VS highlights the "+" character in the Id attribute, and the existence of the length attribute as being errors.将此 XML 加载到 Visual Studio 中后,VS 会突出显示 Id 属性中的“+”字符,并且长度属性的存在是错误的。 I assume that the only way that VS could know this, is if it went and examined the URLs in the Type and xmlns attributes.我假设 VS 可以知道这一点的唯一方法是,它是否检查了 Type 和 xmlns 属性中的 URL。 VS making this type of Internet request is sort of OK to me, as I have given VS permission to do things like check for updates etc, so I already know that it will be visiting the Internet on its own terms. VS 发出这种类型的 Internet 请求对我来说是可以的,因为我已授予 VS 执行检查更新等操作的权限,所以我已经知道它将按照自己的条件访问 Internet。

However, the above XML doesn't deserialize in my command line program unless I remove the xmlns (or force a blank namespace via a custom XML Text Reader), so I am assuming that my command line program is also verifying the xmlns by visiting that URL.但是,上面的 XML 不会在我的命令行程序中反序列化,除非我删除 xmlns(或通过自定义 XML 文本阅读器强制空白命名空间),所以我假设我的命令行程序也通过访问验证 xmlns URL。

This is slightly troubling to me, as although I understand what an xmlns URL is, I haven't explicitly given my program permission to go visit the Internet.这对我来说有点麻烦,因为虽然我了解 xmlns URL 是什么,但我没有明确授予我的程序许可 go 访问 Internet。 In addition, the use case of this program is run locally and analyze some XML generated by another local only program.另外,这个程序的用例是在本地运行的,并分析了另一个本地唯一程序生成的一些XML。 The idea that it could be making Internet requests was way off my radar.它可以发出 Internet 请求的想法远远超出了我的考虑范围。

As well as deserializing this XML, I am also doing some XSLT using the c# XslCompiledTransform class.除了反序列化这个 XML 之外,我还使用 c# XslCompiledTransform ZA14F2ED4F8EB4C2A6BBBD4F2ED4F8EB4C2A6 做一些 XSLT What I finally realized there was that when performing a transform, the xmlns attribute is not something that you can manipulate with XSLT as the transforms are performed on the conceptual data of the XML and not on the raw XML string.我终于意识到,在执行转换时,xmlns 属性不是您可以使用 XSLT 操作的东西,因为转换是在 XML 的概念数据上执行的,而不是在原始 Z3501BB093D3693810B67105 字符串上执行的。 Thus the transform has somehow processed the xmlns when reading the XML.因此,在读取 XML 时,转换以某种方式处理了 xmlns。

My questions are:我的问题是:

  1. Is the XmlSerializer class making an implicit Internet connection to the xmlns? XmlSerializer class 是否与 xmlns 建立隐式 Internet 连接?
  2. Is the XslCompiledTransform class doing something similar? XslCompiledTransform class 是否在做类似的事情?
  3. If there are implicit connections, do they represent a security risk?如果存在隐式连接,它们是否代表安全风险?
  4. And if so, what can be done to mitigate it (aside from forcing a blank namespace)?如果是这样,可以做些什么来减轻它(除了强制使用空白命名空间)?

As per @canton's request, here is the class definition I'm using for the EncryptedData, as well as the fragment showing where it is referenced根据@canton 的要求,这是我用于 EncryptedData 的 class 定义,以及显示它被引用位置的片段

    ...
    [XmlElement("EncryptedData")]
    public EncryptedData EncryptedData { get; set; }
    ...

    public class EncryptedData
    {
        [XmlAttribute("Id")]
        public string Id { get; set; }

        [XmlAttribute("Type")]
        public string Type { get; set; }

        [XmlAttribute("xmlns")]
        public string Xmlns { get; set; }

        [XmlAttribute("length")]
        public int Length { get; set; }

        [XmlElement("EncryptionMethod")]
        public EncryptionMethod EncryptionMethod { get; set; }

        [XmlElement("CipherData")]
        public CipherData CipherData { get; set; }
   }

Firstly, a namespace is not a URL.首先,命名空间不是 URL。 A namespace is just an arbitrary string, The reason that they usually look like URLs is that.命名空间只是一个任意字符串,它们通常看起来像 URL 的原因是这样的。 If everyone uses a URL under a domain that they own or control then there is no chance of a name clash with anyone else's element of the same name.如果每个人都在他们拥有或控制的域下使用 URL,则名称不会与其他任何人的同名元素发生冲突。 Even when the namespace is in URL form there is not usually anything actually there and NO tool will try to access it.即使命名空间在 URL 形式中,通常实际上也没有任何东西,也没有工具会尝试访问它。

Visual Studio maintains a directory of schema files for all Microsoft and standard schemas. Visual Studio 为所有 Microsoft 和标准架构维护一个架构文件目录。 You can add your own there if you want intellisense when editing the XML.如果您在编辑 XML 时需要智能感知,可以在此处添加您自己的。 Check the documentation for the location.检查该位置的文档。

In the absence of an xsd known to VS, the only attribute that is understood by either VS or XmlSerializer is xmlns.在没有 VS 已知的 xsd 的情况下,VS 或 XmlSerializer 理解的唯一属性是 xmlns。

The reason your deserializer wont work is that your elements need to know the namespace.您的反序列化器无法工作的原因是您的元素需要知道名称空间。 It's easy to miss this as all the examples you will see on the internet tend to not use namespaces.很容易错过这一点,因为您将在 Internet 上看到的所有示例都倾向于不使用名称空间。

A good way to go about deserializing is to use xsd.exe to generate classes from either an xsd schema OR a sample data file - The code produces is horrible but can guide you in your prettier version - If you had done this you would have seen that the attributes on the generated code include a namespace eg A good way to go about deserializing is to use xsd.exe to generate classes from either an xsd schema OR a sample data file - The code produces is horrible but can guide you in your prettier version - If you had done this you would have seen生成的代码上的属性包括一个命名空间,例如

[XmlElement("EncryptedData", Namespace="http://www.w3.org/2001/04/xmlenc#"]

When creating this manually it is obviously cleaner to put the namespace in a const string.当手动创建它时,将命名空间放在 const 字符串中显然更干净。

The rules about what does and does not have a namespace qualifier can be quite confusing hence my recommendation to generate sample code first.关于什么有和没有命名空间限定符的规则可能会非常混乱,因此我建议首先生成示例代码。

If you actually want schema validation you have to explicitly do it yourself by passing a validating XmlReader to XmlSerializer ie validation is, optionally, done as part of reading the XML not as part of the deserialization.如果您确实需要模式验证,则必须通过将验证 XmlReader 传递给 XmlSerializer 自己明确地进行验证,即验证是可选的,作为读取 XML 的一部分,而不是作为反序列化的一部分。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM