[英]How to validate xml using a .dtd via a proxy and NOT using system.net.defaultproxy
另一個人已經提出了一個類似的問題: 使用代理針對DTD驗證Xml文件。 C#2.0
這是我的問題:我們有一個網站應用程序,需要同時使用內部和外部資源。
有什么方法可以通過代理通過dtd進行驗證,而無需使用system.net.defaultproxy? 如果我們使用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 Xdocument,然后再次將其關閉?
僅供參考-我對如何解決這個問題持開放態度-請注意,代理位於另一個域中,他們不想為我們的內部Web服務地址在我們的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逗號和代理復雜化。
如果未使用.NET 4.0,則可以自己構建“無網絡”解析器。 為了避免W3C流量限制 ,我自己為XHTML構建了一個自定義解析器 ,也許您可以重復使用它。
另請參閱相關鏈接 。
為了說明,這是自定義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();
}
我的自定義解析器的完整工作代碼可用 。
如果您的解析器進行網絡通信,則對於常規解決方案,您可能需要覆蓋Credentials屬性。
public override System.Net.ICredentials Credentials
{
set { ... }
}
另外,您可能需要公開Proxy屬性。 或不。 如上所述,您可能需要根據DTD URI自動確定要使用的代理。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.