0

MetadataExchenge クラスを使用してクライアント コードへの参照を追加せずに、wcf サービスの動的プロキシを作成しています。問題は、小さな wcf サービスのメタデータをロードするときです。たとえば、メソッドが 1 つまたは 2 つしかないコードは問題なく動作しますが、約 70 から 80 のメソッドを持つ大きな wcf サービスのメタデータをロードしようとすると、最大メッセージ サイズのエラーが発生します。エンドポイントの 1 つで 65536 を超えました...サイズ変数をすべて wcf 構成に最大値に設定しましたが....クライアント側の web.config ファイルには何もありません...すべてを取得しています実行時のバインディング...これについて誰か助けてもらえますか??

4

3 に答える 3

1

コードから Web サービスを使用しようとしているため、クライアント側の web.config には何もありませんか?

サービスを利用するために WsHttpBinding を使用していることを考慮して、次のコードを使用して MaxRecievedMessageSize プロパティを増やします。

System.ServiceModel.WSHttpBinding binding = new System.ServiceModel.WSHttpBinding(System.ServiceModel.SecurityMode.None);

// Increase the message size
binding.MaxReceivedMessageSize = 50000000;

System.ServiceModel.Description.MetadataExchangeClient mexClient = new System.ServiceModel.Description.MetadataExchangeClient(binding);
System.ServiceModel.Description.MetadataSet mexResult = mexClient.GetMetadata(new System.ServiceModel.EndpointAddress("http://someurl:someport/some"));

foreach (System.ServiceModel.Description.MetadataSection section in mexResult.MetadataSections)
{
                Console.WriteLine (section.Identifier);
                Console.WriteLine (section.Metadata.GetType());
                Console.WriteLine ();
}
Console.ReadLine();

これで問題が解決しない場合は、さらに分析するためにコードを投稿するように依頼してください。

于 2012-07-09T10:23:30.300 に答える
1

クライアント側に以下のコードを追加して、次のように readerQuotas を設定できます。

            var binding = se.Binding as BasicHttpBinding;
            binding.MaxBufferSize = 2147483647;
            binding.MaxReceivedMessageSize= 2147483647;
            binding.MaxBufferPoolSize = 2147483647;
            XmlDictionaryReaderQuotas myReaderQuotas = new XmlDictionaryReaderQuotas();
            myReaderQuotas.MaxStringContentLength = 2147483647;
            myReaderQuotas.MaxNameTableCharCount = 2147483647;
            myReaderQuotas.MaxArrayLength= 2147483647;
            myReaderQuotas.MaxBytesPerRead= 2147483647;
            myReaderQuotas.MaxDepth=64;                
            binding.GetType().GetProperty("ReaderQuotas").SetValue(binding, myReaderQuotas, null);

上記のコードは、プロキシのインスタンスを作成する前に設定する必要があります。

于 2012-07-09T13:08:41.320 に答える
0

wcf クライアントを生成する私のコードは次のとおりです。

 try
            {


            Uri mexAddress = new Uri("http://##.##.#.###:8732/WCFTestService/Service1/?wsdl");
            //MetadataSet metaSet1 = MEC.GetMetadata(new EndpointAddress(mexAddress));
            // For MEX endpoints use a MEX address and a 
            // mexMode of .MetadataExchange
            MetadataExchangeClientMode mexMode = MetadataExchangeClientMode.MetadataExchange;

            string contractName = "IVehicleservice";
            string operationName = "ProcessNotification";
            object[] operationParameters = new object[] { 1 };

             //Get the metadata file from the service.
            MetadataExchangeClient mexClient = new MetadataExchangeClient(mexAddress, mexMode);

            mexClient.ResolveMetadataReferences = true;
            mexClient.MaximumResolvedReferences = 100;

            MetadataSet metaSet = mexClient.GetMetadata();


            // Import all contracts and endpoints
            WsdlImporter importer = new WsdlImporter(metaSet);

            Collection<ContractDescription> contracts =
              importer.ImportAllContracts();
            ServiceEndpointCollection allEndpoints = importer.ImportAllEndpoints();

            // Generate type information for each contract
            ServiceContractGenerator generator = new ServiceContractGenerator();
            var endpointsForContracts =
       new Dictionary<string, IEnumerable<ServiceEndpoint>>();

            foreach (ContractDescription contract in contracts)
            {
                generator.GenerateServiceContractType(contract);
                // Keep a list of each contract's endpoints
                endpointsForContracts[contract.Name] = allEndpoints.Where(
                    se => se.Contract.Name == contract.Name).ToList();
            }

            if (generator.Errors.Count != 0)
                throw new Exception("There were errors during code compilation.");

            // Generate a code file for the contracts 
            CodeGeneratorOptions options = new CodeGeneratorOptions();
            options.BracingStyle = "C";
            CodeDomProvider codeDomProvider = CodeDomProvider.CreateProvider("C#");

            // Compile the code file to an in-memory assembly
            // Don't forget to add all WCF-related assemblies as references
            CompilerParameters compilerParameters = new CompilerParameters(
                new string[] { 
                    "System.dll", "System.ServiceModel.dll", 
                    "System.Runtime.Serialization.dll" });
            compilerParameters.GenerateInMemory = true;

            CompilerResults results = codeDomProvider.CompileAssemblyFromDom(
                compilerParameters, generator.TargetCompileUnit);

            if (results.Errors.Count > 0)
            {
                throw new Exception("There were errors during generated code compilation");

            }
            else
            {
                // Find the proxy type that was generated for the specified contract
                // (identified by a class that implements 
                // the contract and ICommunicationbject)
                Type clientProxyType = results.CompiledAssembly.GetTypes().First(
                    t => t.IsClass &&
                        t.GetInterface(contractName) != null &&
                        t.GetInterface(typeof(ICommunicationObject).Name) != null);

                // Get the first service endpoint for the contract
                ServiceEndpoint se = endpointsForContracts[contractName].First();

                // Create an instance of the proxy
                // Pass the endpoint's binding and address as parameters
                // to the ctor
                object instance = results.CompiledAssembly.CreateInstance(
                   clientProxyType.Name,
                    false,
                    System.Reflection.BindingFlags.CreateInstance,
                    null,
                    new object[] { se.Binding, se.Address },
                    CultureInfo.CurrentCulture, null);

                // Get the operation's method, invoke it, and get the return value

                //object retVal = instance.GetType().GetMethod(operationName).
                //    Invoke(instance, operationParameters);

                object retVal = instance.GetType().GetMethod(operationName).
                    Invoke(instance, operationParameters);
                Console.WriteLine(retVal.ToString());

                Console.ReadLine();
            }
        }
        catch(Exception ex)
        { 

        }
于 2012-07-09T12:34:07.310 に答える