gpt4 book ai didi

c# - 如何通过代理使用 .dtd 而不是使用 system.net.defaultproxy 来验证 xml

转载 作者:太空宇宙 更新时间:2023-11-03 14:30:27 29 4
gpt4 key购买 nike

其他人已经问过类似的问题:Validate an Xml file against a DTD with a proxy. C# 2.0

这是我的问题:我们有一个网站应用程序需要使用内部和外部资源。

  1. 我们有一堆内部网页服务。对 CANNOT 的请求通过代理。如果我们尝试这样做,我们会收到 404 错误,因为代理 DNS 不知道我们的内部网络服务域。
  2. 我们生成一个几个必须有效的 xml 文件。我想使用提供的 dtd用于验证 xml 的文档。这dtd url 在我们的网络之外,并且必须通过代理。

有没有办法在不使用 system.net.defaultproxy 的情况下通过代理通过 dtd 进行验证?如果我们使用 defaultproxy,内部 web 服务会被破坏,但 dtd 验证有效。#

这是我现在正在做的验证 xml 的操作:

public static XDocument ValidateXmlUsingDtd(string xml)
{
var xrSettings = new XmlReaderSettings {
ValidationType = ValidationType.DTD,
ProhibitDtd = false
};

var sr = new StringReader(xml.Trim());

XmlReader xRead = XmlReader.Create(sr, xrSettings);
return XDocument.Load(xRead);
}

理想情况下,可以通过某种方式将代理分配给 XmlReader,就像您可以将代理分配给 HttpWebRequest 对象一样。或者也许有一种方法可以以编程方式打开或关闭 defaultproxy?这样我就可以在调用 Load the Xdocument 时打开它,然后再次关闭它?

仅供引用 - 我对如何解决这个问题持开放态度 - 请注意代理位于另一个域中,他们不想为我们的内部网络服务地址设置到我们的 dns 服务器的 dns 查找.

干杯,兰斯

最佳答案

是的,你可以解决这个问题。

一种选择是创建您自己的解析器来处理 DTD 解析。它可以使用任何它喜欢的机制,包括使用非默认代理进行出站通信。

 var xmlReaderSettings = new XmlReaderSettings
{
ProhibitDtd = false,
ValidationType = ValidationType.DTD,
XmlResolver = new MyCustomDtdResolver()
};

在 MyCustomDtdResolver 的代码中,您需要指定所需的代理设置。它可能因 DTD 而异。

您没有指定,但如果您解析的 DTD 是固定不变的,那么 Silverlight 和 .NET 4.0 有一个不访问网络的内置解析器(没有代理,没有任何 http 通信)。它叫做XmlPreloadedResolver .开箱即用,它知道如何解析 RSS091 和 XHTML1.0。如果您有其他 DTD,包括您自己的自定义 DTD,并且它们是固定的或不变的,您可以将它们加载到此解析器中并在运行时使用它,并完全避免 HTTP 通信和代理复杂化。

More on that.

如果您没有使用 .NET 4.0,那么您可以自己构建一个“无网络”解析器。为了避免 W3C traffic limit ,我 build 了a custom resolver myself, for XHTML ,也许您可​​以重复使用它。

另请参阅,a related link .


为了便于说明,这里是自定义 Uri 解析器中 ResolveUri 的代码。

/// <summary>
/// Resolves URIs.
/// </summary>
/// <remarks>
/// <para>
/// The only Uri's supported are those for W3C XHTML 1.0.
/// </para>
/// </remarks>
public override Uri ResolveUri(Uri baseUri, string relativeUri)
{
if (baseUri == null)
{
if (relativeUri.StartsWith("http://"))
{
Trace(" returning {0}", relativeUri);
return new Uri(relativeUri);
}
// throw if Uri scheme is unknown/unhandled
throw new ArgumentException();
}

if (relativeUri == null)
return baseUri;

// both are non-null
var uri = baseUri.AbsoluteUri;
foreach (var key in knownDtds.Keys)
{
// look up the URI in the table of known URIs
var dtdUriRoot = knownDtds[key];
if (uri.StartsWith(dtdUriRoot))
{
string newUri = uri.Substring(0,dtdUriRoot.Length) + relativeUri;
return new Uri(newUri);
}
}

// must throw if Uri is unknown/unhandled
throw new ArgumentException();
}

这是 GetEntity 的代码

/// <summary>
/// Gets the entity associated to the given Uri, role, and
/// Type.
/// </summary>
/// <remarks>
/// <para>
/// The only Type that is supported is the System.IO.Stream.
/// </para>
/// <para>
/// The only Uri's supported are those for W3C XHTML 1.0.
/// </para>
/// </remarks>
public override object GetEntity(Uri absoluteUri, string role, Type t)
{
// only handle streams
if (t != typeof(System.IO.Stream))
throw new ArgumentException();

if (absoluteUri == null)
throw new ArgumentException();

var uri = absoluteUri.AbsoluteUri;
foreach (var key in knownDtds.Keys)
{
if (uri.StartsWith(knownDtds[key]))
{
// Return the stream containing the requested DTD.
// This can be a FileStream, HttpResponseStream, MemoryStream,
// or whatever other stream you like. I used a Resource stream
// myself. If you retrieve the DTDs via HTTP, you could use your
// own IWebProxy here.
var resourceName = GetResourceName(key, uri.Substring(knownDtds[key].Length));
return GetStreamForNamedResource(resourceName);
}
}

throw new ArgumentException();
}

我的自定义解析器的完整工作代码 is available .

如果您的解析器执行网络通信,那么对于一般解决方案,您可能需要覆盖 Credentials 属性。

public override System.Net.ICredentials Credentials
{
set { ... }
}

另外,您可能想要公开一个 Proxy 属性。或不。正如我上面所说,您可能希望根据 DTD URI 自动确定要使用的代理。

关于c# - 如何通过代理使用 .dtd 而不是使用 system.net.defaultproxy 来验证 xml,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2766357/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com