2015-05-04 3 views
0

Мне нужно установить тайм-аут, когда я использую WCF.Установка таймаута в WCF через Reflection

Исключение: исключение типа «System.NullReferenceException», значение переменной propertyInfo равно null. Я не могу получить тайм-аут свойства прокси-типа.

У меня есть следующий код, и у меня есть ошибка, когда я устанавливаю значение. (I зашиты «1000»)

private object GetWCFInstance(ref CompilerResults compilerResults, string WCFAddress, string contractName) 
    { 

     object proxyInstance = null; 
     // Define the WSDL Get address, contract name and parameters, with this we can extract WSDL details any time 
     Uri address = new Uri(WCFAddress); 
     // For HttpGet endpoints use a Service WSDL address a mexMode of .HttpGet and for MEX endpoints use a MEX address and a mexMode of .MetadataExchange 
     MetadataExchangeClientMode mexMode = MetadataExchangeClientMode.HttpGet; 
     //string contractName = "IService1"; 
     // Get the metadata file from the service. 
     MetadataExchangeClient metadataExchangeClient = new MetadataExchangeClient(address, mexMode); 
     metadataExchangeClient.ResolveMetadataReferences = true; 

     //One can also provide credentials if service needs that by the help following two lines. 
     //ICredentials networkCredential = new NetworkCredential("", "", ""); 
     //metadataExchangeClient.HttpCredentials = networkCredential; 

     //Gets the meta data information of the service. 
     MetadataSet metadataSet = metadataExchangeClient.GetMetadata(); 

     // Import all contracts and endpoints. 
     WsdlImporter wsdlImporter = new WsdlImporter(metadataSet); 

     //Import all contracts. 
     Collection<ContractDescription> contracts = wsdlImporter.ImportAllContracts(); 

     //Import all end points. 
     ServiceEndpointCollection allEndpoints = wsdlImporter.ImportAllEndpoints(); 

     // Generate type information for each contract. 
     ServiceContractGenerator serviceContractGenerator = new ServiceContractGenerator(); 

     //Dictinary has been defined to keep all the contract endpoints present, contract name is key of the dictionary item. 
     var endpointsForContracts = new Dictionary<string, IEnumerable<ServiceEndpoint>>(); 

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

     // Generate a code file for the contracts. 
     CodeGeneratorOptions codeGeneratorOptions = new CodeGeneratorOptions(); 
     codeGeneratorOptions.BracingStyle = "C"; 

     // Create Compiler instance of a specified language. 
     CodeDomProvider codeDomProvider = CodeDomProvider.CreateProvider("C#"); 

     // Adding WCF-related assemblies references as copiler parameters, so as to do the compilation of particular service contract. 
     CompilerParameters compilerParameters = new CompilerParameters(new string[] { "System.dll", "System.ServiceModel.dll", "System.Runtime.Serialization.dll" }); 
     compilerParameters.GenerateInMemory = true; 

     //Gets the compiled assembly. 
     compilerResults = codeDomProvider.CompileAssemblyFromDom(compilerParameters, serviceContractGenerator.TargetCompileUnit); 

     if (compilerResults.Errors.Count <= 0) 
     { 
      // Find the proxy type that was generated for the specified contract (identified by a class that implements the contract and ICommunicationbject - this is contract 
      //implemented by all the communication oriented objects). 
      Type proxyType = compilerResults.CompiledAssembly.GetTypes().First(t => t.IsClass && t.GetInterface(contractName) != null && 
       t.GetInterface(typeof(ICommunicationObject).Name) != null); 

      // Now we get the first service endpoint for the particular contract. 
      ServiceEndpoint serviceEndpoint = endpointsForContracts[contractName].First(); 

      // Create an instance of the proxy by passing the endpoint binding and address as parameters. 
      proxyInstance = compilerResults.CompiledAssembly.CreateInstance(proxyType.Name, false, System.Reflection.BindingFlags.CreateInstance, null, 
       new object[] { serviceEndpoint.Binding, serviceEndpoint.Address }, System.Globalization.CultureInfo.CurrentCulture, null); 

      System.Reflection.PropertyInfo propertyInfo = proxyType.GetProperty("Timeout"); 
      **propertyInfo.SetValue(proxyInstance, 1000, null);** 
      object check = propertyInfo.GetValue(proxyInstance, null); 
     } 
     return proxyInstance; 
    }     

Благодаря

ответ

0

Наконец я мог бы решить эту проблему, я ничего в app.config не нужен, то wef.config был настроен с тем же кодом и поставить этот линии в клиенте.

Мне нужно всего лишь наложить ChannelFactory, а затем наложить BasicHttpBinding и установить параметры.

Спасибо всем.

  var timeOut=new TimeSpan(0, 10, 0); 
      int timeOutInt = 2147483647; 
      PropertyInfo channelFactoryProperty = proxyInstance.GetType().GetProperty("ChannelFactory"); 

     if (channelFactoryProperty == null) 
     { 
      throw new InvalidOperationException("There is no ''ChannelFactory'' property on the DomainClient."); 
     } 
     ChannelFactory factory = (ChannelFactory)channelFactoryProperty.GetValue(proxyInstance, null); 
     factory.Endpoint.Binding.SendTimeout = timeOut; 
     factory.Endpoint.Binding.OpenTimeout = timeOut; 
     factory.Endpoint.Binding.ReceiveTimeout = timeOut; 
     factory.Endpoint.Binding.CloseTimeout = timeOut; 

     BasicHttpBinding _binding = (BasicHttpBinding)factory.Endpoint.Binding; 
     _binding.MaxBufferPoolSize = timeOutInt; 
     _binding.MaxBufferSize = timeOutInt; 
     _binding.MaxReceivedMessageSize = timeOutInt; 
     _binding.OpenTimeout = timeOut;