2

wsdl.exe ツールを使用して wsdl ファイルから自動生成された .NET Web サービス クライアントがあります。

生成されたクラスを最初にインスタンス化すると、w3.org などから一連のドキュメントを要求し始めます。最初のものはhttp://www.w3.org/2001/XMLSchema.dtd です

w3.org に不必要なトラフィックを発生させたくないだけでなく、インターネットに接続せずにアプリケーションを実行できるようにする必要があります (Web サービスは「イントラ Web サービス」です)。

誰でも解決策を知っていますか?

それが役立つ場合は、インターネットがないときに取得するスタックトレースを次に示します。

"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

4 に答える 4

4

XmlReader (または XmlTextReader) にアクセスできる場合は、次のことができます。

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

よろしく、タンバーグ

于 2008-10-20T11:31:05.807 に答える
4

XmlResolver が必要だったので、tamberg のソリューションはうまくいきませんでした。必要なスキーマをダウンロードする代わりに埋め込みリソースから読み取る独自の XmlResolver を実装することで解決しました。

ちなみに、この問題は自動生成されたコードとは何の関係もありませんでした。

web-service-client には、次のようなものを含む別の実装ファイルがありました。

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();
    }

失敗したのはこのクラスコンストラクターでした。

于 2008-10-20T11:38:50.877 に答える
1

これが私の解決策です。私が XmlUrlResolver の基盤を解決しなければならなかったように、誰かが .NET フレームワークを介してデバッグする必要がなくなることを願っています。ローカル リソース (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, @"_");
        }
    }
}
于 2012-02-18T06:25:54.903 に答える
0

タンバーグに感謝します。あなたの簡潔で正しい答えにより、多くの時間を節約できました。デフォルトのリゾルバーが Web に移行するとは知りませんでした。MSDN の状態を確認しています -

XmlResolver は、System.Xml 名前空間のすべてのクラスの既定のリゾルバーです。独自のリゾルバーを作成することもできます...

問題を解決し、ネットワークのオーバーヘッドを削減する NULL にリゾルバーを設定して、回答を実装しました。

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

ありがとう、アンディ

于 2009-03-27T11:56:51.570 に答える