2008-10-20 16 views
2

我有一個使用wsdl.exe工具從wsdl文件自動生成的.NET Web服務客戶端。.NET自動生成的Web服務客戶端:如何避免從w3.org請求模式?

當我第一次實例化生成的類時,它開始向w3.org和其他人請求一堆文檔。第一個是http://www.w3.org/2001/XMLSchema.dtd

除了不想造成不必要的流量到w3.org,我需要能夠運行沒有連接到互聯網的應用程序(網絡服務是「Intra-web-service」 )。

任何人都知道解決方案嗎?

如果有幫助,這裏是堆棧跟蹤的時候,我沒有上網,我得到:

"An error has occurred while opening external DTD 'http://www.w3.org/2001/XMLSchema.dtd': The remote name could not be resolved: 'www.w3.org'" 

    at System.Net.HttpWebRequest.GetResponse() 
    at System.Xml.XmlDownloadManager.GetNonFileStream(Uri uri, ICredentials credentials) 
    at System.Xml.XmlDownloadManager.GetStream(Uri uri, ICredentials credentials) 
    at System.Xml.XmlUrlResolver.GetEntity(Uri absoluteUri, String role, Type ofObjectToReturn) 
    at System.Xml.XmlTextReaderImpl.OpenStream(Uri uri) 
    at System.Xml.XmlTextReaderImpl.DtdParserProxy_PushExternalSubset(String systemId, String publicId) 

    at System.Xml.XmlTextReaderImpl.Throw(Exception e) 
    at System.Xml.XmlTextReaderImpl.DtdParserProxy_PushExternalSubset(String systemId, String publicId) 
    at System.Xml.XmlTextReaderImpl.DtdParserProxy.System.Xml.IDtdParserAdapter.PushExternalSubset(String systemId, String publicId) 
    at System.Xml.DtdParser.ParseExternalSubset() 
    at System.Xml.DtdParser.ParseInDocumentDtd(Boolean saveInternalSubset) 
    at System.Xml.DtdParser.Parse(Boolean saveInternalSubset) 
    at System.Xml.XmlTextReaderImpl.DtdParserProxy.Parse(Boolean saveInternalSubset) 
    at System.Xml.XmlTextReaderImpl.ParseDoctypeDecl() 
    at System.Xml.XmlTextReaderImpl.ParseDocumentContent() 
    at System.Xml.XmlTextReaderImpl.Read() 
    at System.Xml.Schema.Parser.StartParsing(XmlReader reader, String targetNamespace) 
    at System.Xml.Schema.Parser.Parse(XmlReader reader, String targetNamespace) 
    at System.Xml.Schema.XmlSchemaSet.ParseSchema(String targetNamespace, XmlReader reader) 
    at System.Xml.Schema.XmlSchemaSet.Add(String targetNamespace, XmlReader schemaDocument) 
    at [...]WebServiceClientType..cctor() in [...] 

回答

4

我需要XmlResolver,所以tamberg's solution不太合適。我通過實現我自己的XmlResolver來解決它,它從嵌入式資源中讀取必要的模式,而不是下載它們。

順便說一下,問題與自動生成的代碼沒有任何關係。

的Web服務客戶端必須包含這樣的另一個實現文件:

public partial class [...]WebServiceClientType 
    { 
    private static readonly XmlSchemaSet _schema; 

    static KeyImportFileType() 
    { 
     _schema = new XmlSchemaSet(); 
     _schema.Add(null, XmlResourceResolver.GetXmlReader("http://www.w3.org/TR/2002/REC-xmldsig-core-20020212/xmldsig-core-schema.xsd")); 
     _schema.Add(null, XmlResourceResolver.GetXmlReader("http://www.w3.org/TR/2002/REC-xmlenc-core-20021210/xenc-schema.xsd")); 
     _schema.Compile(); 
    } 

,這是這個類的構造函數失敗。

4

,如果你有機會獲得的XmlReader(或XmlTextReader的),你可以做到以下幾點:

XmlReader r = ... 
r.XmlResolver = null; // prevent xsd or dtd parsing 

Regards, tamberg

0

謝謝坦伯格,你用簡潔和正確的答案爲我節省了大量的時間。我沒有意識到默認的解析器會上網。正在檢查MSDN狀態 -

XmlResolver是System.Xml命名空間中所有類的默認解析器。您也可以創建自己的解析器...

我實現你的答案,設置解析器爲NULL解決了問題,並降低了網絡開銷。再次

XmlReader r = ...r.XmlResolver = null; // prevent xsd or dtd parsing 

感謝, 安迪

1

這裏是我的解決方案。我希望它能夠避免某些人不得不通過.NET框架進行調試,就像我必須制定XmlUrlResolver的基礎一樣。它將從本地資源(resx文本文件)加載,緩存或使用XmlUrlResolver默認行爲:

using System; 
using System.Text; 
using System.Text.RegularExpressions; 
using System.Xml; 
using System.Net; 
using System.Net.Cache; 
using System.IO; 
using System.Resources; 

namespace AxureExport { 

    // 
    // redirect URL resolution to local resource (or cache) 
    public class XmlCustomResolver : XmlUrlResolver { 

     ICredentials _credentials; 
     ResourceManager _resourceManager; 

     public enum ResolverType { useDefault, useCache, useResource }; 
     ResolverType _resolverType; 

     public XmlCustomResolver(ResolverType rt, ResourceManager rm = null) { 
      _resourceManager = rm != null ? rm : AxureExport.Properties.Resources.ResourceManager; 
      _resolverType = rt; 
     } 

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

     public override object GetEntity(Uri absoluteUri, string role, Type ofObjectToReturn) { 
      object response = null; 

      if (absoluteUri == null) 
       throw new ArgumentNullException(@"absoluteUri"); 

      switch (_resolverType) { 
       default: 
       case ResolverType.useDefault:     // use the default behavior of the XmlUrlResolver 
        response = defaultResponse(absoluteUri, role, ofObjectToReturn); 
        break; 

       case ResolverType.useCache:      // resolve resources thru cache 
        if (!isExternalRequest(absoluteUri, ofObjectToReturn)) { 
         response = defaultResponse(absoluteUri, role, ofObjectToReturn); 
         break; 
        } 

        WebRequest webReq = WebRequest.Create(absoluteUri); 
        webReq.CachePolicy = new HttpRequestCachePolicy(HttpRequestCacheLevel.Default); 
        if (_credentials != null) 
         webReq.Credentials = _credentials; 

        WebResponse wr = webReq.GetResponse(); 
        response = wr.GetResponseStream(); 
        break; 

       case ResolverType.useResource:     // get resource from internal resource 
        if (!isExternalRequest(absoluteUri, ofObjectToReturn)) { 
         response = defaultResponse(absoluteUri, role, ofObjectToReturn); // not an external request 
         break; 
        } 

        string resourceName = uriToResourceKey(absoluteUri); 
        object resource = _resourceManager.GetObject(resourceName); 
        if (resource == null) 
         throw new ArgumentException(@"Resource not found. Uri=" + absoluteUri + @" Local resourceName=" + resourceName); 

        if (resource.GetType() != typeof(System.String)) 
         throw new ArgumentException(resourceName + @" is an unexpected resource type. (Are you setting resource FileType=Text?)"); 

        response = ObjectToUTF8Stream(resource); 
        break; 
      } 

      return response; 
     } 

     // 
     // convert object to stream 
     private static object ObjectToUTF8Stream(object o) { 
      MemoryStream stream = new MemoryStream(); 

      StreamWriter writer = new StreamWriter(stream, Encoding.UTF8); 
      writer.Write(o); 
      writer.Flush(); 
      stream.Position = 0; 

      return stream; 
     } 

     // 
     // default response is to call tbe base resolver 
     private object defaultResponse(Uri absoluteUri, string role, Type ofObjectToReturn) { 
      return base.GetEntity(absoluteUri, role, ofObjectToReturn); 
     } 

     // 
     // determine whether this is an external request 
     private static bool isExternalRequest(Uri absoluteUri, Type ofObjectToReturn) { 
      return absoluteUri.Scheme == @"http" && (ofObjectToReturn == null || ofObjectToReturn == typeof(Stream)); 
     } 

     // 
     // translate uri to format compatible with reource manager key naming rules 
     // see: System.Resources.Tools.StronglyTypedResourceBuilder.VerifyResourceName Method 
     // from http://msdn.microsoft.com/en-us/library/ms145952.aspx: 
     private static string uriToResourceKey(Uri absoluteUri) { 
      const string repl = @"[ \xA0\.\,\;\|\~\@\#\%\^\&\*\+\-\/\\\<\>\?\[\]\(\)\{\}\" + "\"" + @"\'\:\!]+"; 
      return Regex.Replace(Path.GetFileNameWithoutExtension(absoluteUri.LocalPath), repl, @"_"); 
     } 
    } 
} 
相關問題