e79aa3c0ed
Former-commit-id: a2155e9bd80020e49e72e86c44da02a8ac0e57a4
556 lines
25 KiB
C#
556 lines
25 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.ComponentModel;
|
|
using System.Diagnostics;
|
|
using System.Runtime;
|
|
using System.Runtime.Diagnostics;
|
|
using System.ServiceModel.Channels;
|
|
using System.ServiceModel.Diagnostics;
|
|
using System.ServiceModel.Dispatcher;
|
|
using System.Xml;
|
|
|
|
public class ServiceMetadataBehavior : IServiceBehavior
|
|
{
|
|
public const string MexContractName = "IMetadataExchange";
|
|
internal const string MexContractNamespace = "http://schemas.microsoft.com/2006/04/mex";
|
|
|
|
static readonly Uri emptyUri = new Uri(String.Empty, UriKind.Relative);
|
|
|
|
bool httpGetEnabled = false;
|
|
bool httpsGetEnabled = false;
|
|
Uri httpGetUrl;
|
|
Uri httpsGetUrl;
|
|
Binding httpGetBinding;
|
|
Binding httpsGetBinding;
|
|
Uri externalMetadataLocation = null;
|
|
MetadataExporter metadataExporter = null;
|
|
|
|
static ContractDescription mexContract = null;
|
|
static object thisLock = new object();
|
|
|
|
public bool HttpGetEnabled
|
|
{
|
|
get { return this.httpGetEnabled; }
|
|
set { this.httpGetEnabled = value; }
|
|
}
|
|
|
|
[TypeConverter(typeof(UriTypeConverter))]
|
|
public Uri HttpGetUrl
|
|
{
|
|
get { return this.httpGetUrl; }
|
|
set
|
|
{
|
|
if (value != null && value.IsAbsoluteUri && value.Scheme != Uri.UriSchemeHttp)
|
|
{
|
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(SR.GetString(SR.SFxServiceMetadataBehaviorUrlMustBeHttpOrRelative,
|
|
"HttpGetUrl", Uri.UriSchemeHttp, value.ToString(), value.Scheme));
|
|
}
|
|
this.httpGetUrl = value;
|
|
}
|
|
}
|
|
|
|
public bool HttpsGetEnabled
|
|
{
|
|
get { return this.httpsGetEnabled; }
|
|
set { this.httpsGetEnabled = value; }
|
|
}
|
|
|
|
[TypeConverter(typeof(UriTypeConverter))]
|
|
public Uri HttpsGetUrl
|
|
{
|
|
get { return this.httpsGetUrl; }
|
|
set
|
|
{
|
|
if (value != null && value.IsAbsoluteUri && value.Scheme != Uri.UriSchemeHttps)
|
|
{
|
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(SR.GetString(SR.SFxServiceMetadataBehaviorUrlMustBeHttpOrRelative,
|
|
"HttpsGetUrl", Uri.UriSchemeHttps, value.ToString(), value.Scheme));
|
|
}
|
|
|
|
this.httpsGetUrl = value;
|
|
}
|
|
}
|
|
|
|
public Binding HttpGetBinding
|
|
{
|
|
get { return this.httpGetBinding; }
|
|
set
|
|
{
|
|
if (value != null)
|
|
{
|
|
if (!value.Scheme.Equals(Uri.UriSchemeHttp, StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(SR.GetString(SR.SFxBindingSchemeDoesNotMatch,
|
|
value.Scheme, value.GetType().ToString(), Uri.UriSchemeHttp));
|
|
}
|
|
CustomBinding customBinding = new CustomBinding(value);
|
|
TextMessageEncodingBindingElement textMessageEncodingBindingElement = customBinding.Elements.Find<TextMessageEncodingBindingElement>();
|
|
if (textMessageEncodingBindingElement != null && !textMessageEncodingBindingElement.MessageVersion.IsMatch(MessageVersion.None))
|
|
{
|
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(SR.GetString(SR.SFxIncorrectMessageVersion,
|
|
textMessageEncodingBindingElement.MessageVersion.ToString(), MessageVersion.None.ToString()));
|
|
}
|
|
HttpTransportBindingElement httpTransportBindingElement = customBinding.Elements.Find<HttpTransportBindingElement>();
|
|
if (httpTransportBindingElement != null)
|
|
{
|
|
httpTransportBindingElement.Method = "GET";
|
|
}
|
|
this.httpGetBinding = customBinding;
|
|
}
|
|
}
|
|
}
|
|
|
|
public Binding HttpsGetBinding
|
|
{
|
|
get { return this.httpsGetBinding; }
|
|
set
|
|
{
|
|
if (value != null)
|
|
{
|
|
if (!value.Scheme.Equals(Uri.UriSchemeHttps, StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(SR.GetString(SR.SFxBindingSchemeDoesNotMatch,
|
|
value.Scheme, value.GetType().ToString(), Uri.UriSchemeHttps));
|
|
}
|
|
CustomBinding customBinding = new CustomBinding(value);
|
|
TextMessageEncodingBindingElement textMessageEncodingBindingElement = customBinding.Elements.Find<TextMessageEncodingBindingElement>();
|
|
if (textMessageEncodingBindingElement != null && !textMessageEncodingBindingElement.MessageVersion.IsMatch(MessageVersion.None))
|
|
{
|
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(SR.GetString(SR.SFxIncorrectMessageVersion,
|
|
textMessageEncodingBindingElement.MessageVersion.ToString(), MessageVersion.None.ToString()));
|
|
}
|
|
HttpsTransportBindingElement httpsTransportBindingElement = customBinding.Elements.Find<HttpsTransportBindingElement>();
|
|
if (httpsTransportBindingElement != null)
|
|
{
|
|
httpsTransportBindingElement.Method = "GET";
|
|
}
|
|
this.httpsGetBinding = customBinding;
|
|
}
|
|
}
|
|
}
|
|
|
|
[TypeConverter(typeof(UriTypeConverter))]
|
|
|
|
public Uri ExternalMetadataLocation
|
|
{
|
|
get { return this.externalMetadataLocation; }
|
|
set
|
|
{
|
|
if (value != null && value.IsAbsoluteUri && !(value.Scheme == Uri.UriSchemeHttp || value.Scheme == Uri.UriSchemeHttps))
|
|
{
|
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("ExternalMetadataLocation", SR.GetString(SR.SFxBadMetadataLocationUri, value.OriginalString, value.Scheme));
|
|
}
|
|
this.externalMetadataLocation = value;
|
|
}
|
|
}
|
|
|
|
public MetadataExporter MetadataExporter
|
|
{
|
|
get
|
|
{
|
|
if (this.metadataExporter == null)
|
|
this.metadataExporter = new WsdlExporter();
|
|
|
|
return this.metadataExporter;
|
|
}
|
|
set
|
|
{
|
|
this.metadataExporter = value;
|
|
}
|
|
}
|
|
|
|
static internal ContractDescription MexContract
|
|
{
|
|
get
|
|
{
|
|
EnsureMexContractDescription();
|
|
return ServiceMetadataBehavior.mexContract;
|
|
}
|
|
}
|
|
|
|
void IServiceBehavior.Validate(ServiceDescription description, ServiceHostBase serviceHostBase)
|
|
{
|
|
}
|
|
|
|
void IServiceBehavior.AddBindingParameters(ServiceDescription description, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection parameters)
|
|
{
|
|
}
|
|
|
|
void IServiceBehavior.ApplyDispatchBehavior(ServiceDescription description, ServiceHostBase serviceHostBase)
|
|
{
|
|
if (description == null)
|
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("description");
|
|
if (serviceHostBase == null)
|
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("serviceHostBase");
|
|
|
|
ApplyBehavior(description, serviceHostBase);
|
|
}
|
|
|
|
void ApplyBehavior(ServiceDescription description, ServiceHostBase host)
|
|
{
|
|
ServiceMetadataExtension mex = ServiceMetadataExtension.EnsureServiceMetadataExtension(description, host);
|
|
SetExtensionProperties(description, host, mex);
|
|
CustomizeMetadataEndpoints(description, host, mex);
|
|
CreateHttpGetEndpoints(description, host, mex);
|
|
}
|
|
|
|
private void CreateHttpGetEndpoints(ServiceDescription description, ServiceHostBase host, ServiceMetadataExtension mex)
|
|
{
|
|
bool httpDispatcherEnabled = false;
|
|
bool httpsDispatcherEnabled = false;
|
|
|
|
if (this.httpGetEnabled)
|
|
{
|
|
httpDispatcherEnabled = EnsureGetDispatcher(host, mex, this.httpGetUrl, Uri.UriSchemeHttp);
|
|
}
|
|
|
|
if (this.httpsGetEnabled)
|
|
{
|
|
httpsDispatcherEnabled = EnsureGetDispatcher(host, mex, this.httpsGetUrl, Uri.UriSchemeHttps);
|
|
}
|
|
|
|
if (!httpDispatcherEnabled && !httpsDispatcherEnabled)
|
|
{
|
|
if (this.httpGetEnabled)
|
|
{
|
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxServiceMetadataBehaviorNoHttpBaseAddress)));
|
|
}
|
|
|
|
if (this.httpsGetEnabled)
|
|
{
|
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxServiceMetadataBehaviorNoHttpsBaseAddress)));
|
|
}
|
|
}
|
|
}
|
|
|
|
static bool EnsureGetDispatcher(ServiceHostBase host, ServiceMetadataExtension mex, Uri url, string scheme)
|
|
{
|
|
Uri address = host.GetVia(scheme, url == null ? new Uri(string.Empty, UriKind.Relative) : url);
|
|
|
|
if (address != null)
|
|
{
|
|
ChannelDispatcher channelDispatcher = mex.EnsureGetDispatcher(address, false /* isServiceDebugBehavior */);
|
|
((ServiceMetadataExtension.HttpGetImpl)channelDispatcher.Endpoints[0].DispatchRuntime.SingletonInstanceContext.UserObject).GetWsdlEnabled = true;
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void SetExtensionProperties(ServiceDescription description, ServiceHostBase host, ServiceMetadataExtension mex)
|
|
{
|
|
mex.ExternalMetadataLocation = this.ExternalMetadataLocation;
|
|
mex.Initializer = new MetadataExtensionInitializer(this, description, host);
|
|
mex.HttpGetEnabled = this.httpGetEnabled;
|
|
mex.HttpsGetEnabled = this.httpsGetEnabled;
|
|
|
|
mex.HttpGetUrl = host.GetVia(Uri.UriSchemeHttp, this.httpGetUrl == null ? new Uri(string.Empty, UriKind.Relative) : this.httpGetUrl);
|
|
mex.HttpsGetUrl = host.GetVia(Uri.UriSchemeHttps, this.httpsGetUrl == null ? new Uri(string.Empty, UriKind.Relative) : this.httpsGetUrl);
|
|
|
|
mex.HttpGetBinding = this.httpGetBinding;
|
|
mex.HttpsGetBinding = this.httpsGetBinding;
|
|
|
|
UseRequestHeadersForMetadataAddressBehavior dynamicUpdateBehavior = description.Behaviors.Find<UseRequestHeadersForMetadataAddressBehavior>();
|
|
if (dynamicUpdateBehavior != null)
|
|
{
|
|
mex.UpdateAddressDynamically = true;
|
|
mex.UpdatePortsByScheme = new Dictionary<string, int>(dynamicUpdateBehavior.DefaultPortsByScheme);
|
|
}
|
|
|
|
foreach (ChannelDispatcherBase dispatcherBase in host.ChannelDispatchers)
|
|
{
|
|
ChannelDispatcher dispatcher = dispatcherBase as ChannelDispatcher;
|
|
if (dispatcher != null && IsMetadataTransferDispatcher(description, dispatcher))
|
|
{
|
|
mex.MexEnabled = true;
|
|
mex.MexUrl = dispatcher.Listener.Uri;
|
|
if (dynamicUpdateBehavior != null)
|
|
{
|
|
foreach (EndpointDispatcher endpointDispatcher in dispatcher.Endpoints)
|
|
{
|
|
if (!endpointDispatcher.AddressFilterSetExplicit)
|
|
{
|
|
endpointDispatcher.AddressFilter = new MatchAllMessageFilter();
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
private static void CustomizeMetadataEndpoints(ServiceDescription description, ServiceHostBase host, ServiceMetadataExtension mex)
|
|
{
|
|
for (int i = 0; i < host.ChannelDispatchers.Count; i++)
|
|
{
|
|
ChannelDispatcher channelDispatcher = host.ChannelDispatchers[i] as ChannelDispatcher;
|
|
if (channelDispatcher != null && ServiceMetadataBehavior.IsMetadataTransferDispatcher(description, channelDispatcher))
|
|
{
|
|
if (channelDispatcher.Endpoints.Count != 1)
|
|
{
|
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
|
|
new InvalidOperationException(SR.GetString(SR.SFxServiceMetadataBehaviorInstancingError, channelDispatcher.Listener.Uri, channelDispatcher.CreateContractListString())));
|
|
}
|
|
|
|
DispatchRuntime dispatcher = channelDispatcher.Endpoints[0].DispatchRuntime;
|
|
|
|
// set instancing
|
|
dispatcher.InstanceContextProvider =
|
|
InstanceContextProviderBase.GetProviderForMode(InstanceContextMode.Single, dispatcher);
|
|
|
|
bool isListeningOnHttps = channelDispatcher.Listener.Uri.Scheme == Uri.UriSchemeHttps;
|
|
Uri listenUri = channelDispatcher.Listener.Uri;
|
|
ServiceMetadataExtension.WSMexImpl impl = new ServiceMetadataExtension.WSMexImpl(mex, isListeningOnHttps, listenUri);
|
|
dispatcher.SingletonInstanceContext = new InstanceContext(host, impl, false);
|
|
}
|
|
}
|
|
}
|
|
|
|
static EndpointDispatcher GetListenerByID(SynchronizedCollection<ChannelDispatcherBase> channelDispatchers, string id)
|
|
{
|
|
for (int i = 0; i < channelDispatchers.Count; ++i)
|
|
{
|
|
ChannelDispatcher channelDispatcher = channelDispatchers[i] as ChannelDispatcher;
|
|
if (channelDispatcher != null)
|
|
{
|
|
for (int j = 0; j < channelDispatcher.Endpoints.Count; ++j)
|
|
{
|
|
EndpointDispatcher endpointDispatcher = channelDispatcher.Endpoints[j];
|
|
if (endpointDispatcher.Id == id)
|
|
return endpointDispatcher;
|
|
}
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
internal static bool IsMetadataDispatcher(ServiceDescription description, ChannelDispatcher channelDispatcher)
|
|
{
|
|
foreach (EndpointDispatcher endpointDispatcher in channelDispatcher.Endpoints)
|
|
{
|
|
if (IsMetadataTransferDispatcher(description, channelDispatcher)
|
|
|| IsHttpGetMetadataDispatcher(description, channelDispatcher))
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
static bool IsMetadataTransferDispatcher(ServiceDescription description, ChannelDispatcher channelDispatcher)
|
|
{
|
|
if (BehaviorMissingObjectNullOrServiceImplements(description, channelDispatcher))
|
|
return false;
|
|
|
|
foreach (EndpointDispatcher endpointDispatcher in channelDispatcher.Endpoints)
|
|
{
|
|
if (endpointDispatcher.ContractName == ServiceMetadataBehavior.MexContractName
|
|
&& endpointDispatcher.ContractNamespace == ServiceMetadataBehavior.MexContractNamespace)
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
private static bool BehaviorMissingObjectNullOrServiceImplements(ServiceDescription description, object obj)
|
|
{
|
|
if (obj == null)
|
|
return true;
|
|
if (description.Behaviors != null && description.Behaviors.Find<ServiceMetadataBehavior>() == null)
|
|
return true;
|
|
if (description.ServiceType != null && description.ServiceType.GetInterface(typeof(IMetadataExchange).Name) != null)
|
|
return true;
|
|
|
|
return false;
|
|
}
|
|
|
|
internal static bool IsHttpGetMetadataDispatcher(ServiceDescription description, ChannelDispatcher channelDispatcher)
|
|
{
|
|
if (description.Behaviors.Find<ServiceMetadataBehavior>() == null)
|
|
return false;
|
|
|
|
foreach (EndpointDispatcher endpointDispatcher in channelDispatcher.Endpoints)
|
|
{
|
|
if (endpointDispatcher.ContractName == ServiceMetadataExtension.HttpGetImpl.ContractName
|
|
&& endpointDispatcher.ContractNamespace == ServiceMetadataExtension.HttpGetImpl.ContractNamespace)
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
internal static bool IsMetadataEndpoint(ServiceDescription description, ServiceEndpoint endpoint)
|
|
{
|
|
if (BehaviorMissingObjectNullOrServiceImplements(description, endpoint))
|
|
return false;
|
|
|
|
return IsMetadataEndpoint(endpoint);
|
|
|
|
}
|
|
|
|
static bool IsMetadataEndpoint(ServiceEndpoint endpoint)
|
|
{
|
|
return (endpoint.Contract.Name == ServiceMetadataBehavior.MexContractName
|
|
&& endpoint.Contract.Namespace == ServiceMetadataBehavior.MexContractNamespace);
|
|
}
|
|
|
|
internal static bool IsMetadataImplementedType(ServiceDescription description, Type type)
|
|
{
|
|
if (BehaviorMissingObjectNullOrServiceImplements(description, type))
|
|
return false;
|
|
|
|
return type == typeof(IMetadataExchange);
|
|
}
|
|
|
|
internal static bool IsMetadataImplementedType(Type type)
|
|
{
|
|
return type == typeof(IMetadataExchange);
|
|
}
|
|
|
|
internal void AddImplementedContracts(ServiceHostBase.ServiceAndBehaviorsContractResolver resolver)
|
|
{
|
|
if (!resolver.BehaviorContracts.ContainsKey(MexContractName))
|
|
{
|
|
resolver.BehaviorContracts.Add(MexContractName, ServiceMetadataBehavior.MexContract);
|
|
}
|
|
}
|
|
|
|
static void EnsureMexContractDescription()
|
|
{
|
|
if (ServiceMetadataBehavior.mexContract == null)
|
|
{
|
|
lock (thisLock)
|
|
{
|
|
if (ServiceMetadataBehavior.mexContract == null)
|
|
{
|
|
ServiceMetadataBehavior.mexContract = CreateMexContract();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static ContractDescription CreateMexContract()
|
|
{
|
|
ContractDescription mexContract = ContractDescription.GetContract(typeof(IMetadataExchange));
|
|
foreach (OperationDescription operation in mexContract.Operations)
|
|
{
|
|
operation.Behaviors.Find<OperationBehaviorAttribute>().Impersonation = ImpersonationOption.Allowed;
|
|
}
|
|
mexContract.Behaviors.Add(new ServiceMetadataContractBehavior(true));
|
|
|
|
return mexContract;
|
|
|
|
}
|
|
|
|
internal class MetadataExtensionInitializer
|
|
{
|
|
ServiceMetadataBehavior behavior;
|
|
ServiceDescription description;
|
|
ServiceHostBase host;
|
|
Exception metadataGenerationException = null;
|
|
|
|
internal MetadataExtensionInitializer(ServiceMetadataBehavior behavior, ServiceDescription description, ServiceHostBase host)
|
|
{
|
|
this.behavior = behavior;
|
|
this.description = description;
|
|
this.host = host;
|
|
}
|
|
|
|
internal MetadataSet GenerateMetadata()
|
|
{
|
|
if (this.behavior.ExternalMetadataLocation == null || this.behavior.ExternalMetadataLocation.ToString() == string.Empty)
|
|
{
|
|
if (this.metadataGenerationException != null)
|
|
throw this.metadataGenerationException;
|
|
|
|
try
|
|
{
|
|
MetadataExporter exporter = this.behavior.MetadataExporter;
|
|
XmlQualifiedName serviceName = new XmlQualifiedName(this.description.Name, this.description.Namespace);
|
|
Collection<ServiceEndpoint> exportedEndpoints = new Collection<ServiceEndpoint>();
|
|
foreach (ServiceEndpoint endpoint in this.description.Endpoints)
|
|
{
|
|
ServiceMetadataContractBehavior contractBehavior = endpoint.Contract.Behaviors.Find<ServiceMetadataContractBehavior>();
|
|
|
|
// if contract behavior exists, generate metadata when the behavior allows metadata generation
|
|
// if contract behavior doesn't exist, generate metadata only for non system endpoints
|
|
if ((contractBehavior != null && !contractBehavior.MetadataGenerationDisabled) ||
|
|
(contractBehavior == null && !endpoint.IsSystemEndpoint))
|
|
{
|
|
EndpointAddress address = null;
|
|
EndpointDispatcher endpointDispatcher = GetListenerByID(this.host.ChannelDispatchers, endpoint.Id);
|
|
if (endpointDispatcher != null)
|
|
{
|
|
address = endpointDispatcher.EndpointAddress;
|
|
}
|
|
ServiceEndpoint exportedEndpoint = new ServiceEndpoint(endpoint.Contract);
|
|
exportedEndpoint.Binding = endpoint.Binding;
|
|
exportedEndpoint.Name = endpoint.Name;
|
|
exportedEndpoint.Address = address;
|
|
foreach (IEndpointBehavior behavior in endpoint.Behaviors)
|
|
{
|
|
exportedEndpoint.Behaviors.Add(behavior);
|
|
}
|
|
exportedEndpoints.Add(exportedEndpoint);
|
|
}
|
|
}
|
|
WsdlExporter wsdlExporter = exporter as WsdlExporter;
|
|
if (wsdlExporter != null)
|
|
{
|
|
// Pass the BindingParameterCollection into the ExportEndpoints method so that the binding parameters can be using to export WSDL correctly.
|
|
// The binding parameters are used in BuildChannelListener, during which they can modify the configuration of the channel in ways that might have to
|
|
// be communicated in the WSDL. For example, in the case of Multi-Auth, the AuthenticationSchemesBindingParameter is used during BuildChannelListener
|
|
// to set the AuthenticationSchemes supported by the virtual directory on the HttpTransportBindingElement. These authentication schemes also need
|
|
// to be in the WSDL, so that clients know what authentication schemes are supported by the service. (see CSDMain #180381)
|
|
Fx.Assert(this.host != null, "ServiceHostBase field on MetadataExtensionInitializer should never be null.");
|
|
wsdlExporter.ExportEndpoints(exportedEndpoints, serviceName, this.host.GetBindingParameters(exportedEndpoints));
|
|
}
|
|
else
|
|
{
|
|
foreach (ServiceEndpoint endpoint in exportedEndpoints)
|
|
{
|
|
exporter.ExportEndpoint(endpoint);
|
|
}
|
|
}
|
|
|
|
if (exporter.Errors.Count > 0 && DiagnosticUtility.ShouldTraceWarning)
|
|
{
|
|
TraceWsdlExportErrors(exporter);
|
|
}
|
|
|
|
return exporter.GetGeneratedMetadata();
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
this.metadataGenerationException = e;
|
|
throw;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
static void TraceWsdlExportErrors(MetadataExporter exporter)
|
|
{
|
|
foreach (MetadataConversionError error in exporter.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);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|