![](/img/trans.png)
[英]Host our ASP.NET Core MVC is returning this error "403 Forbidden error was encountered while trying to use an ErrorDocument to handle the request.."
[英]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.