我正在创建 wcf 服务的 dyanminc 代理,而不使用 MetadataExchenge 类添加对客户端代码的引用。问题是当我加载小型 wcf 服务的元数据时,例如只有 1 或 2 个方法,代码对我来说工作正常,但是当我尝试加载具有大约 70 到 80 个方法的大型 wcf 服务的元数据时,我收到最大消息大小的错误其中一个端点已超过 65536...尽管我已将 wcf 配置中的所有大小变量都设置为最大值...我的客户端 web.config 文件中没有任何内容...我得到了所有运行时的绑定...有人可以帮忙吗?
问问题
1157 次
3 回答
1
您在客户端 web.config 上没有任何东西,因为您正试图从代码中使用 Web 服务?
考虑到您使用 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 回答