3

私たちの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か月間は問題なく機能しました。しかし、1〜2週間後、このコードで次のエラーが発生することがありました。

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 

最初はインターネットプロキシポリシーの変更によるものだと思っていましたが、別のプロキシの背後にあるアプリの別の展開で発見されたので、それは非常に疑わしいです。

エラーは多かれ少なかれランダムであるように思われ、機能する場合と機能しない場合があります。なぜこのように動作するのか、私にはわかりません。

質問は:なぜこれが起こるのかあなたは何か考えがありますか?はいの場合、それを修正する方法を知っていますか?いいえの場合、回避策のアイデアはありますか?

4

2 に答える 2

1

結局、私は自家製のクラスを使って仕事をしました。これは、XmlUrlResolver拡張機能のMSDN実装から着想を得ています。MSDNリソースを指摘したリンクを指摘してくれた@mzjnに感謝します。

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);
            }
        }
    }
}
于 2013-03-13T07:34:32.757 に答える
0

私はあなたがこれの周りにいくつかのロジックを試してみる必要があると思います、私はどこかからバッファリングされました

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

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

or 

 request.Credentials = CredentialCache.DefaultCredentials;
于 2013-03-18T07:23:52.023 に答える