簡體   English   中英

使用我們的應用程序打開SVG時DTD上的錯誤403(禁止)

[英]Error 403 (Forbidden) on the DTD while opening a SVG with our application

在我們的C#應用程序中,有時應用程序需要打開一個svg文件。 為此,使用以下代碼:

XmlReaderSettings settings = new XmlReaderSettings();
settings.ProhibitDtd = false;
settings.ValidationType = ValidationType.None;
XmlReader xr = XmlReader.Create(serverMainPath + @"/path/to/svg/file.svg", settings);
XmlDocument xd = new XmlDocument();
_nmsm = new XmlNamespaceManager(xd.NameTable);
_nmsm.AddNamespace("svg", "http://www.w3.org/2000/svg");
_nmsm.AddNamespace("v", "http://schemas.microsoft.com/visio/2003/SVGExtensions/");
xd.Load(xr);

我們使用的標准svg開頭(據我所知它是一個有效的svg):

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
    <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
    <!-- Généré par Microsoft Visio 11.0, SVG Export, v1.0 svgIncluded.svg Page-1 -->
    <svg xmlns="http://www.w3.org/2000/svg" xmlns:v="http://schemas.microsoft.com/visio/2003/SVGExtensions/" width="8.26772in" height="11.6929in" viewBox="0 0 595.276 841.889" xml:space="preserve" color-interpolation-filters="sRGB" class="st23" >

在過去的6個月里它運作得很好。 但是,由於一到兩周,此代碼有時會產生以下錯誤:

Server Error in '/ourApp' Application.
--------------------------------------------------------------------------------

The remote server returned an error: (403) Forbidden. 
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. 

Exception Details: System.Net.WebException: The remote server returned an error: (403) Forbidden.

Source Error: 

Line 40:                 _nmsm.AddNamespace("svg", "http://www.w3.org/2000/svg");
Line 41:                 _nmsm.AddNamespace("v", "http://schemas.microsoft.com/visio/2003/SVGExtensions/");
Line 42:                 xd.Load(xr);


Source File: path/to/the/file/file.cs    Line: 42 

Stack Trace: 

[WebException: The remote server returned an error: (403) Forbidden.]
   System.Net.HttpWebRequest.GetResponse() +5400333
   System.Xml.XmlDownloadManager.GetNonFileStream(Uri uri, ICredentials credentials) +69
   System.Xml.XmlDownloadManager.GetStream(Uri uri, ICredentials credentials) +3929515
   System.Xml.XmlUrlResolver.GetEntity(Uri absoluteUri, String role, Type ofObjectToReturn) +54
   System.Xml.XmlTextReaderImpl.OpenStream(Uri uri) +34
   System.Xml.XmlTextReaderImpl.DtdParserProxy_PushExternalSubset(String systemId, String publicId) +380

[XmlException: An error has occurred while opening external DTD 'http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd': The remote server returned an error: (403) Forbidden.]
   System.Xml.XmlTextReaderImpl.Throw(Exception e) +76
   System.Xml.XmlTextReaderImpl.DtdParserProxy_PushExternalSubset(String systemId, String publicId) +513
   System.Xml.DtdParserProxy.System.Xml.IDtdParserAdapter.PushExternalSubset(String systemId, String publicId) +16
   System.Xml.DtdParser.ParseExternalSubset() +21
   System.Xml.DtdParser.ParseInDocumentDtd(Boolean saveInternalSubset) +4017069
   System.Xml.DtdParser.Parse(Boolean saveInternalSubset) +54
   System.Xml.DtdParserProxy.Parse(Boolean saveInternalSubset) +31
   System.Xml.XmlTextReaderImpl.ParseDoctypeDecl() +254
   System.Xml.XmlTextReaderImpl.ParseDocumentContent() +451
   System.Xml.XmlTextReaderImpl.Read() +151
   System.Xml.XmlLoader.LoadNode(Boolean skipOverWhitespace) +58
   System.Xml.XmlLoader.LoadDocSequence(XmlDocument parentDoc) +20
   System.Xml.XmlLoader.Load(XmlDocument doc, XmlReader reader, Boolean preserveWhitespace) +129
   System.Xml.XmlDocument.Load(XmlReader reader) +108
   OurMethod(params) in path/to/the/file/file.cs:42
   StackTrace in our App.

--------------------------------------------------------------------------------
Version Information: Microsoft .NET Framework Version:2.0.50727.3643; ASP.NET Version:2.0.50727.3634 

起初我認為這是由於我們的互聯網代理政策發生了變化,但由於它已經被發現在另一個不同代理的應用程序部署中,我非常懷疑。

錯誤似乎或多或少隨機,有時它會起作用,有時它不會。 我只是不知道為什么會這樣做。

問題是:你知道為什么會發生這種情況嗎? 如果是,你知道如何解決它嗎? 如果不是,任何解決方法的想法?

最后,我用了一個自制的班級來完成這項工作。 它的靈感來自XmlUrlResolver擴展MSDN實現 感謝@mzjn指出了指向MSDN資源的鏈接。

using System;
using System.Net;
using System.Net.Cache;
using System.Xml;
using System.IO;

namespace My.Nasmespace.Class.IO
{
    class XmlExtendedResolver : XmlUrlResolver
    {
        bool enableHttpCaching;
        ICredentials credentials;
        private string localServerPath;
        //resolve ressource from localServerPath if it's possible
        //resolve resources from cache (if possible) when enableHttpCaching is set to true 
        //resolve resources from source when enableHttpcaching is set to false  
        public XmlExtendedResolver(bool enableHttpCaching, string serverPath)
        {
            this.enableHttpCaching = enableHttpCaching;
            localServerPath = serverPath;
        }

        public override ICredentials Credentials
        {
            set
            {
                credentials = value;
                base.Credentials = value;
            }
        }

        public override object GetEntity(Uri absoluteUri, string role, Type ofObjectToReturn)
        {
            if (absoluteUri == null)
            {
                throw new ArgumentNullException("absoluteUri");
            }
            //resolve resources from cache (if possible) 
            if (absoluteUri.Scheme == "http" && enableHttpCaching && (ofObjectToReturn == null || ofObjectToReturn == typeof(Stream)))
            {
                /*Try to resolve it from the local path if it exists*/
                if (!string.IsNullOrEmpty(localServerPath) && absoluteUri.AbsolutePath.EndsWith(".dtd") && !absoluteUri.AbsoluteUri.StartsWith(localServerPath))
                {
                    try { 
                        return GetEntity(new Uri(localServerPath + "/Xml/" + absoluteUri.Segments[absoluteUri.Segments.Length-1]), role, ofObjectToReturn);
                    } catch (FileNotFoundException){
                         //Fail silently to go to the web request.
                    }
                }
                WebRequest webReq = WebRequest.Create(absoluteUri);
                webReq.CachePolicy = new    HttpRequestCachePolicy(HttpRequestCacheLevel.Default);
                if (credentials != null)
                {
                    webReq.Credentials = credentials;
                }
                WebResponse resp = webReq.GetResponse();
                return resp.GetResponseStream();
            }
            //otherwise use the default behavior of the XmlUrlResolver class (resolve resources from source) 
        else
            {
                return base.GetEntity(absoluteUri, role, ofObjectToReturn);
            }
        }
    }
}

我認為你必須嘗試一些邏輯,我只是​​從一些地方緩沖

request.UserAgent = "userAgents";
request.Accept = "*/*";

request.Credentials = new NetworkCredentials("username", "password");

or 

 request.Credentials = CredentialCache.DefaultCredentials;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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