簡體   English   中英

如何通過代理使用.dtd而不是使用system.net.defaultproxy來驗證xml

[英]How to validate xml using a .dtd via a proxy and NOT using system.net.defaultproxy

另一個人已經提出了一個類似的問題: 使用代理針對DTD驗證Xml文件。 C#2.0

這是我的問題:我們有一個網站應用程序,需要同時使用內部和外部資源。

  1. 我們有很多內部網絡服務。 對CANNOT的請求不能通過代理。 如果嘗試這樣做,由於代理DNS不了解我們的內部Web服務域,我們將收到404錯誤。
  2. 我們生成一些必須有效的xml文件。 我想使用提供的dtd文檔來驗證xml。 dtd網址在我們的網絡之外,必須通過代理。

有什么方法可以通過代理通過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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM