2008-10-20 15 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, @"_"); 
     } 
    } 
} 
相关问题