316 lines
13 KiB
C#
316 lines
13 KiB
C#
|
//------------------------------------------------------------
|
||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||
|
//------------------------------------------------------------
|
||
|
namespace System.ServiceModel.Description
|
||
|
{
|
||
|
using System.Collections;
|
||
|
using System.Collections.Generic;
|
||
|
using System.Collections.ObjectModel;
|
||
|
using System.Diagnostics;
|
||
|
using System.Runtime;
|
||
|
using System.Runtime.Diagnostics;
|
||
|
using System.ServiceModel;
|
||
|
using System.ServiceModel.Diagnostics;
|
||
|
using System.Xml;
|
||
|
|
||
|
public static class MetadataResolver
|
||
|
{
|
||
|
public static ServiceEndpointCollection Resolve(Type contract, EndpointAddress address)
|
||
|
{
|
||
|
if (contract == null)
|
||
|
{
|
||
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("contract");
|
||
|
}
|
||
|
|
||
|
return Resolve(CreateContractCollection(contract), address);
|
||
|
}
|
||
|
public static ServiceEndpointCollection Resolve(IEnumerable<ContractDescription> contracts, EndpointAddress address)
|
||
|
{
|
||
|
return Resolve(contracts, address, new MetadataExchangeClient(address));
|
||
|
}
|
||
|
public static ServiceEndpointCollection Resolve(IEnumerable<ContractDescription> contracts, EndpointAddress address, MetadataExchangeClient client)
|
||
|
{
|
||
|
if (address == null)
|
||
|
{
|
||
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("address");
|
||
|
}
|
||
|
if (client == null)
|
||
|
{
|
||
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("client");
|
||
|
}
|
||
|
if (contracts == null)
|
||
|
{
|
||
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("contracts");
|
||
|
}
|
||
|
ValidateContracts(contracts);
|
||
|
|
||
|
|
||
|
MetadataSet metadataSet = client.GetMetadata(address);
|
||
|
return ImportEndpoints(metadataSet, contracts, client);
|
||
|
}
|
||
|
|
||
|
public static ServiceEndpointCollection Resolve(Type contract, Uri address, MetadataExchangeClientMode mode)
|
||
|
{
|
||
|
if (contract == null)
|
||
|
{
|
||
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("contract");
|
||
|
}
|
||
|
|
||
|
return Resolve(CreateContractCollection(contract), address, mode);
|
||
|
}
|
||
|
public static ServiceEndpointCollection Resolve(IEnumerable<ContractDescription> contracts, Uri address, MetadataExchangeClientMode mode)
|
||
|
{
|
||
|
return Resolve(contracts, address, mode, new MetadataExchangeClient(address, mode));
|
||
|
}
|
||
|
public static ServiceEndpointCollection Resolve(IEnumerable<ContractDescription> contracts, Uri address, MetadataExchangeClientMode mode, MetadataExchangeClient client)
|
||
|
{
|
||
|
if (address == null)
|
||
|
{
|
||
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("address");
|
||
|
}
|
||
|
MetadataExchangeClientModeHelper.Validate(mode);
|
||
|
if (client == null)
|
||
|
{
|
||
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("client");
|
||
|
}
|
||
|
if (contracts == null)
|
||
|
{
|
||
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("contracts");
|
||
|
}
|
||
|
ValidateContracts(contracts);
|
||
|
|
||
|
MetadataSet metadataSet = client.GetMetadata(address, mode);
|
||
|
return ImportEndpoints(metadataSet, contracts, client);
|
||
|
}
|
||
|
|
||
|
public static IAsyncResult BeginResolve(Type contract, EndpointAddress address, AsyncCallback callback, object asyncState)
|
||
|
{
|
||
|
if (contract == null)
|
||
|
{
|
||
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("contract");
|
||
|
}
|
||
|
|
||
|
return BeginResolve(CreateContractCollection(contract), address, callback, asyncState);
|
||
|
}
|
||
|
public static IAsyncResult BeginResolve(IEnumerable<ContractDescription> contracts, EndpointAddress address, AsyncCallback callback, object asyncState)
|
||
|
{
|
||
|
return BeginResolve(contracts, address, new MetadataExchangeClient(address), callback, asyncState);
|
||
|
}
|
||
|
public static IAsyncResult BeginResolve(IEnumerable<ContractDescription> contracts, EndpointAddress address, MetadataExchangeClient client, AsyncCallback callback, object asyncState)
|
||
|
{
|
||
|
if (address == null)
|
||
|
{
|
||
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("address");
|
||
|
}
|
||
|
if (client == null)
|
||
|
{
|
||
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("client");
|
||
|
}
|
||
|
if (contracts == null)
|
||
|
{
|
||
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("contracts");
|
||
|
}
|
||
|
ValidateContracts(contracts);
|
||
|
|
||
|
return new AsyncMetadataResolverHelper(address, MetadataExchangeClientMode.MetadataExchange, client, contracts, callback, asyncState);
|
||
|
}
|
||
|
|
||
|
public static IAsyncResult BeginResolve(Type contract, Uri address, MetadataExchangeClientMode mode, AsyncCallback callback, object asyncState)
|
||
|
{
|
||
|
if (contract == null)
|
||
|
{
|
||
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("contract");
|
||
|
}
|
||
|
|
||
|
return BeginResolve(CreateContractCollection(contract), address, mode, callback, asyncState);
|
||
|
}
|
||
|
public static IAsyncResult BeginResolve(IEnumerable<ContractDescription> contracts, Uri address, MetadataExchangeClientMode mode, AsyncCallback callback, object asyncState)
|
||
|
{
|
||
|
return BeginResolve(contracts, address, mode, new MetadataExchangeClient(address, mode), callback, asyncState);
|
||
|
}
|
||
|
public static IAsyncResult BeginResolve(IEnumerable<ContractDescription> contracts, Uri address, MetadataExchangeClientMode mode, MetadataExchangeClient client,
|
||
|
AsyncCallback callback, object asyncState)
|
||
|
{
|
||
|
if (address == null)
|
||
|
{
|
||
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("address");
|
||
|
}
|
||
|
MetadataExchangeClientModeHelper.Validate(mode);
|
||
|
if (client == null)
|
||
|
{
|
||
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("client");
|
||
|
}
|
||
|
if (contracts == null)
|
||
|
{
|
||
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("contracts");
|
||
|
}
|
||
|
ValidateContracts(contracts);
|
||
|
|
||
|
return new AsyncMetadataResolverHelper(new EndpointAddress(address), mode, client, contracts, callback, asyncState);
|
||
|
}
|
||
|
|
||
|
public static ServiceEndpointCollection EndResolve(IAsyncResult result)
|
||
|
{
|
||
|
return AsyncMetadataResolverHelper.EndAsyncCall(result);
|
||
|
}
|
||
|
|
||
|
class AsyncMetadataResolverHelper : AsyncResult
|
||
|
{
|
||
|
MetadataExchangeClient client;
|
||
|
EndpointAddress address;
|
||
|
ServiceEndpointCollection endpointCollection;
|
||
|
MetadataExchangeClientMode mode;
|
||
|
IEnumerable<ContractDescription> knownContracts;
|
||
|
|
||
|
internal AsyncMetadataResolverHelper(EndpointAddress address, MetadataExchangeClientMode mode, MetadataExchangeClient client, IEnumerable<ContractDescription> knownContracts, AsyncCallback callback, object asyncState)
|
||
|
: base(callback, asyncState)
|
||
|
{
|
||
|
this.address = address;
|
||
|
this.client = client;
|
||
|
this.mode = mode;
|
||
|
this.knownContracts = knownContracts;
|
||
|
|
||
|
GetMetadataSetAsync();
|
||
|
}
|
||
|
|
||
|
internal void GetMetadataSetAsync()
|
||
|
{
|
||
|
IAsyncResult result;
|
||
|
|
||
|
if (this.mode == MetadataExchangeClientMode.HttpGet)
|
||
|
{
|
||
|
result = this.client.BeginGetMetadata(this.address.Uri, MetadataExchangeClientMode.HttpGet, Fx.ThunkCallback(new AsyncCallback(this.EndGetMetadataSet)), null);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
result = this.client.BeginGetMetadata(this.address, Fx.ThunkCallback(new AsyncCallback(this.EndGetMetadataSet)), null);
|
||
|
}
|
||
|
|
||
|
if (result.CompletedSynchronously)
|
||
|
{
|
||
|
HandleResult(result);
|
||
|
this.Complete(true);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
internal void EndGetMetadataSet(IAsyncResult result)
|
||
|
{
|
||
|
if (result.CompletedSynchronously)
|
||
|
return;
|
||
|
|
||
|
Exception exception = null;
|
||
|
try
|
||
|
{
|
||
|
HandleResult(result);
|
||
|
|
||
|
}
|
||
|
catch (Exception e)
|
||
|
{
|
||
|
if (Fx.IsFatal(e))
|
||
|
throw;
|
||
|
exception = e;
|
||
|
}
|
||
|
this.Complete(false, exception);
|
||
|
|
||
|
}
|
||
|
|
||
|
private void HandleResult(IAsyncResult result)
|
||
|
{
|
||
|
MetadataSet metadataSet = this.client.EndGetMetadata(result);
|
||
|
endpointCollection = ImportEndpoints(metadataSet, knownContracts, this.client);
|
||
|
}
|
||
|
|
||
|
internal static ServiceEndpointCollection EndAsyncCall(IAsyncResult result)
|
||
|
{
|
||
|
AsyncMetadataResolverHelper helper = AsyncResult.End<AsyncMetadataResolverHelper>(result);
|
||
|
return helper.endpointCollection;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private static ServiceEndpointCollection ImportEndpoints(MetadataSet metadataSet, IEnumerable<ContractDescription> contracts, MetadataExchangeClient client)
|
||
|
{
|
||
|
ServiceEndpointCollection endpoints = new ServiceEndpointCollection();
|
||
|
|
||
|
WsdlImporter importer = new WsdlImporter(metadataSet);
|
||
|
|
||
|
// remember the original proxy so user doesn't need to set it again
|
||
|
importer.State.Add(MetadataExchangeClient.MetadataExchangeClientKey, client);
|
||
|
|
||
|
foreach (ContractDescription cd in contracts)
|
||
|
{
|
||
|
importer.KnownContracts.Add(WsdlExporter.WsdlNamingHelper.GetPortTypeQName(cd), cd);
|
||
|
}
|
||
|
|
||
|
foreach (ContractDescription cd in contracts)
|
||
|
{
|
||
|
ServiceEndpointCollection contractEndpoints;
|
||
|
contractEndpoints = importer.ImportEndpoints(cd);
|
||
|
foreach (ServiceEndpoint se in contractEndpoints)
|
||
|
{
|
||
|
endpoints.Add(se);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//Trace all warnings and errors
|
||
|
if (importer.Errors.Count > 0)
|
||
|
{
|
||
|
TraceWsdlImportErrors(importer);
|
||
|
}
|
||
|
|
||
|
return endpoints;
|
||
|
}
|
||
|
|
||
|
static void TraceWsdlImportErrors(WsdlImporter importer)
|
||
|
{
|
||
|
foreach (MetadataConversionError error in importer.Errors)
|
||
|
{
|
||
|
if (DiagnosticUtility.ShouldTraceWarning)
|
||
|
{
|
||
|
Hashtable h = new Hashtable(2)
|
||
|
{
|
||
|
{ "IsWarning", error.IsWarning },
|
||
|
{ "Message", error.Message }
|
||
|
};
|
||
|
TraceUtility.TraceEvent(TraceEventType.Warning, TraceCode.WsmexNonCriticalWsdlExportError,
|
||
|
SR.GetString(SR.TraceCodeWsmexNonCriticalWsdlExportError), new DictionaryTraceRecord(h), null, null);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private static void ValidateContracts(IEnumerable<ContractDescription> contracts)
|
||
|
{
|
||
|
bool isEmpty = true;
|
||
|
Collection<XmlQualifiedName> qnames = new Collection<XmlQualifiedName>();
|
||
|
foreach (ContractDescription cd in contracts)
|
||
|
{
|
||
|
isEmpty = false;
|
||
|
if (cd == null)
|
||
|
{
|
||
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(SR.GetString(SR.SFxMetadataResolverKnownContractsCannotContainNull));
|
||
|
}
|
||
|
|
||
|
XmlQualifiedName qname = WsdlExporter.WsdlNamingHelper.GetPortTypeQName(cd);
|
||
|
if (qnames.Contains(qname))
|
||
|
{
|
||
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(SR.GetString(SR.SFxMetadataResolverKnownContractsUniqueQNames, qname.Name, qname.Namespace));
|
||
|
}
|
||
|
|
||
|
qnames.Add(qname);
|
||
|
}
|
||
|
|
||
|
if (isEmpty)
|
||
|
{
|
||
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(SR.GetString(SR.SFxMetadataResolverKnownContractsArgumentCannotBeEmpty));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private static Collection<ContractDescription> CreateContractCollection(Type contract)
|
||
|
{
|
||
|
Collection<ContractDescription> contracts = new Collection<ContractDescription>();
|
||
|
contracts.Add(ContractDescription.GetContract(contract));
|
||
|
return contracts;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|