コード例 #1
0
ファイル: WCFBuildProvider.cs プロジェクト: dox0/DotNet471RS3
        /// <summary>
        /// Check the result from the code generator.
        /// By default we treat all error messages from WsdlImporter as warnings,
        /// and they will be ignored if valid code has been generated.
        /// We may hit other errors when we parse the metadata files.
        /// Those errors (which are usually because of a bad file) will not be ignored, because the user can fix them.
        /// If the WsdlImporter hasn't generated any code as we expect, we have to consider some of the error messages are fatal.
        /// We collect those messages and report to the user.
        /// </summary>
        /// <param name="referenceDisplayName">The name of the generated reference</param>
        /// <param name="mapFile">Original Map File</param>
        /// <param name="generatedCode">generated code compile unit</param>
        /// <param name="importErrors"></param>
        /// <param name="generatorErrors"></param>
        /// <remarks></remarks>
        private static void VerifyGeneratedCodeAndHandleErrors(
            string referenceDisplayName,
            SvcMapFile mapFile,
            CodeCompileUnit generatedCode,
            System.Collections.IEnumerable importErrors,
            System.Collections.IEnumerable generatorErrors)
        {
            // Check and report fatal error first...
            HandleProxyGenerationErrors(importErrors);
            HandleProxyGenerationErrors(generatorErrors);

            // if there is no fatal error, we expect valid type generated from the process
            //   unless there is no metadata files, or there is a service contract type sharing
            if (mapFile.MetadataList.Count > 0 && mapFile.ClientOptions.ServiceContractMappingList.Count == 0)
            {
                if (!IsAnyTypeGenerated(generatedCode))
                {
                    StringBuilder collectedMessages = new StringBuilder();

                    // merge error messages
                    CollectErrorMessages(importErrors, collectedMessages);
                    CollectErrorMessages(generatorErrors, collectedMessages);

                    throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, WCFModelStrings.ReferenceGroup_FailedToGenerateCode, referenceDisplayName, collectedMessages.ToString()));
                }
            }
        }
コード例 #2
0
ファイル: WCFBuildProvider.cs プロジェクト: dox0/DotNet471RS3
        private CodeCompileUnit GenerateCodeFromServiceMapFile(string mapFilePath)
        {
            try
            {
                string           generatedNamespace = GetGeneratedNamespace();
                SvcMapFileLoader loader             = new SvcMapFileLoader(mapFilePath);
                SvcMapFile       mapFile            = loader.LoadMapFile() as SvcMapFile;

                HandleProxyGenerationErrors(mapFile.LoadErrors);

                // We always use C# for the generated proxy
                CodeDomProvider provider = System.CodeDom.Compiler.CodeDomProvider.CreateProvider("c#");

                //Note: with the current implementation of the generator, it does all of its
                //  work in the constructor.  This may change in the future.
                VSWCFServiceContractGenerator generator = VSWCFServiceContractGenerator.GenerateCodeAndConfiguration(
                    mapFile,
                    GetToolConfig(mapFile, mapFilePath),
                    provider,
                    generatedNamespace,
                    null, //targetConfiguration
                    null, //configurationNamespace
                    new ImportExtensionServiceProvider(),
                    new TypeResolver(),
                    FRAMEWORK_VERSION_35,
                    typeof(System.Data.Design.TypedDataSetSchemaImporterExtensionFx35)  //Always we are above framework version 3.5
                    );

                // Determine what "name" to display to users for the service if there are any exceptions
                // If generatedNamespace is empty, then we display the name of the .svcmap file.
                string referenceDisplayName = String.IsNullOrEmpty(generatedNamespace) ?
                                              System.IO.Path.GetFileName(mapFilePath) : generatedNamespace;

                VerifyGeneratedCodeAndHandleErrors(referenceDisplayName, mapFile, generator.TargetCompileUnit, generator.ImportErrors, generator.ProxyGenerationErrors);
#if DEBUG
#if false
                IO.TextWriter        writer  = new IO.StringWriter();
                CodeGeneratorOptions options = new CodeGeneratorOptions();
                options.BlankLinesBetweenMembers = true;
                provider.GenerateCodeFromCompileUnit(generator.TargetCompileUnit, writer, options);
                Debug.WriteLine("Generated proxy code:\r\n" + writer.ToString());
#endif
#endif
                return(generator.TargetCompileUnit);
            }
            catch (Exception ex)
            {
                string errorMessage = ex.Message;
                errorMessage = String.Format(CultureInfo.CurrentCulture, "{0}: {1}", IO.Path.GetFileName(mapFilePath), errorMessage);
                throw new InvalidOperationException(errorMessage, ex);
            }
        }
コード例 #3
0
ファイル: WCFBuildProvider.cs プロジェクト: dox0/DotNet471RS3
        /// <summary>
        /// Get the appropriate tool configuration for this service reference.
        ///
        /// If a reference.config file is present, the configuration object returned
        /// will be the merged view of:
        ///
        ///    Machine Config
        ///       ReferenceConfig
        ///
        /// If not reference.config file is present, the configuration object returned
        /// will be a merged view of:
        ///
        ///     Machine.config
        ///         web.config in application's physical path...
        ///
        /// </summary>
        /// <param name="mapFile">SvcMapFile representing the service</param>
        /// <returns></returns>
        private System.Configuration.Configuration GetToolConfig(SvcMapFile mapFile, string mapFilePath)
        {
            string toolConfigFile = null;

            if (mapFile != null && mapFilePath != null)
            {
                foreach (ExtensionFile extensionFile in mapFile.Extensions)
                {
                    if (String.Equals(extensionFile.Name, TOOL_CONFIG_ITEM_NAME, StringComparison.Ordinal))
                    {
                        toolConfigFile = extensionFile.FileName;
                    }
                }
            }

            System.Web.Configuration.WebConfigurationFileMap fileMap;
            fileMap = new System.Web.Configuration.WebConfigurationFileMap();

            System.Web.Configuration.VirtualDirectoryMapping mapping;
            if (toolConfigFile != null)
            {
                //
                // If we've got a specific tool configuration to use, we better load that...
                //
                mapping = new System.Web.Configuration.VirtualDirectoryMapping(System.IO.Path.GetDirectoryName(mapFilePath), true, toolConfigFile);
            }
            else
            {
                //
                // Otherwise we fall back to the default web.config file...
                //
                mapping = new System.Web.Configuration.VirtualDirectoryMapping(HostingEnvironment.ApplicationPhysicalPath, true);
            }
            fileMap.VirtualDirectories.Add("/", mapping);

            return(System.Web.Configuration.WebConfigurationManager.OpenMappedWebConfiguration(fileMap, "/", System.Web.Hosting.HostingEnvironment.SiteName));
        }
コード例 #4
0
        /// <summary>
        /// Factory method: generate code and return the resulting VSWCFServiceContractGenerator. 
        /// </summary>
        /// <param name="svcMapFile">
        /// The SvcMapFile that lists the metadata and generation options for the service reference.
        /// </param>
        /// <param name="toolConfiguration">
        /// Configuration from which we are going to pick up WSDL and policy importer extensions as well
        /// as custom MEX bindings for metadata download. May be Null/Nothing.
        /// </param>
        /// <param name="codeDomProvider">
        /// CodeDom provider that is to be used to generate the client code.
        /// </param>
        /// <param name="proxyNamespace">
        /// CLR namespace in which to generate the client code.
        /// </param>
        /// <param name="targetConfiguration">
        /// The configuration into which we will put bindings/endpoints for this service
        /// reference. May be Null/Nothing.
        /// </param>
        /// <param name="configurationNamespace">
        /// The namespace that is to be used in configuration for this service reference.
        /// </param>
        /// <param name="serviceProviderForImportExtensions">
        /// Service provider that we'll pass on to import extensions that accept our site:ing
        /// mechanism
        /// </param>
        /// <param name="typeLoader">
        /// Type loader that can be used to find reference assemblies and/or resolve shared service and
        /// data contract types.
        /// </param>
        /// <param name="targetFrameworkVersion">
        /// The target framework version number. The higher 16 bits contains the major version number, and low 16 bits contains minor version number.
        /// </param>
        /// <param name="typedDataSetSchemaImporterExtension">
        /// Schema importer extension to be used for typed datasets.
        /// </param>
        /// <returns>
        /// A VSWCFServiceContractGenerator instance that contains the result of the generation. To get
        /// hold of the generated information, you can query it's properties.
        /// </returns>
        public static VSWCFServiceContractGenerator GenerateCodeAndConfiguration(SvcMapFile svcMapFile,
                                             System.Configuration.Configuration toolConfiguration,
                                             System.CodeDom.Compiler.CodeDomProvider codeDomProvider,
                                             string proxyNamespace,
                                             System.Configuration.Configuration targetConfiguration,
                                             string configurationNamespace,
                                             IServiceProvider serviceProviderForImportExtensions,
                                             IContractGeneratorReferenceTypeLoader typeLoader,
                                             int targetFrameworkVersion,
                                             System.Type typedDataSetSchemaImporterExtension)
        {
            if (svcMapFile == null) throw new ArgumentNullException("svcMapFile");
            if (codeDomProvider == null) throw new ArgumentNullException("codeDomProvider");
            if (typedDataSetSchemaImporterExtension == null) throw new ArgumentNullException("typedDataSetSchemaImporterExtension");

            List<ProxyGenerationError> importErrors = new List<ProxyGenerationError>();
            List<ProxyGenerationError> proxyGenerationErrors = new List<ProxyGenerationError>();

            CodeCompileUnit targetCompileUnit = new CodeCompileUnit();

            WsdlImporter wsdlImporter = CreateWsdlImporter(svcMapFile,
                                                           toolConfiguration,
                                                           targetCompileUnit,
                                                           codeDomProvider,
                                                           proxyNamespace,
                                                           serviceProviderForImportExtensions,
                                                           typeLoader,
                                                           targetFrameworkVersion,
                                                           importErrors,
                                                           typedDataSetSchemaImporterExtension);

            ServiceContractGenerator contractGenerator = CreateContractGenerator(svcMapFile.ClientOptions,
                                                                                wsdlImporter,
                                                                                targetCompileUnit,
                                                                                proxyNamespace,
                                                                                targetConfiguration,
                                                                                typeLoader,
                                                                                targetFrameworkVersion,
                                                                                importErrors);

            try
            {
                List<ServiceEndpoint> serviceEndpointList = new List<ServiceEndpoint>();
                IEnumerable<System.ServiceModel.Channels.Binding> bindingCollection;
                IEnumerable<ContractDescription> contractCollection;

                ImportWCFModel(wsdlImporter,
                                 targetCompileUnit,
                                 importErrors,
                                 out serviceEndpointList,
                                 out bindingCollection,
                                 out contractCollection);

                Dictionary<ServiceEndpoint, ChannelEndpointElement> serviceEndpointToChannelEndpointElementMap;
                List<GeneratedContractType> proxyGeneratedContractTypes;

                GenerateProxy(wsdlImporter,
                              contractGenerator,
                              targetCompileUnit,
                              proxyNamespace,
                              configurationNamespace,
                              contractCollection,
                              bindingCollection,
                              serviceEndpointList,
                              proxyGenerationErrors,
                              out serviceEndpointToChannelEndpointElementMap,
                              out proxyGeneratedContractTypes);

                if (IsVBCodeDomProvider(codeDomProvider))
                {
                    PatchOutParametersInVB(targetCompileUnit);
                }

                return new VSWCFServiceContractGenerator(importErrors,
                                                         targetCompileUnit,
                                                         targetConfiguration,
                                                         bindingCollection,
                                                         contractCollection,
                                                         serviceEndpointList,
                                                         serviceEndpointToChannelEndpointElementMap,
                                                         proxyGeneratedContractTypes,
                                                         proxyGenerationErrors);
            }
            catch (Exception ex)
            {
                // fatal error... (workaround for 


                proxyGenerationErrors.Add(new ProxyGenerationError(
                                    ProxyGenerationError.GeneratorState.GenerateCode,
                                    String.Empty,
                                    ex,
                                    false));

                return new VSWCFServiceContractGenerator(importErrors,
                                                        new CodeCompileUnit(),
                                                        targetConfiguration,
                                                        new List<System.ServiceModel.Channels.Binding>(),
                                                        new List<ContractDescription>(),
                                                        new List<ServiceEndpoint>(),
                                                        new Dictionary<ServiceEndpoint, ChannelEndpointElement>(),
                                                        new List<GeneratedContractType>(),
                                                        proxyGenerationErrors);
            }

        }
コード例 #5
0
        /// <summary>
        /// Creates a dictionary containing a copy of the contents of all of the extension files
        /// </summary>
        /// <returns></returns>
        private static Dictionary<string, byte[]> CreateDictionaryOfCopiedExtensionFiles(SvcMapFile svcMapFile)
        {
            Dictionary<string, byte[]> extensionFileContents = new Dictionary<string, byte[]>();
            foreach (ExtensionFile extensionFile in svcMapFile.Extensions)
            {
                // If the extension file was not successfully loaded, do not include it in the
                //   collection.  Users are more likely to expect that the extension file won't
                //   be in the collection on an error than they are to assume they have to check
                //   if the byte array we return is null or not.
                if (extensionFile.ContentBuffer != null && extensionFile.IsBufferValid)
                {
                    extensionFileContents.Add(extensionFile.Name, (byte[])extensionFile.ContentBuffer.Clone());
                }
            }

            return extensionFileContents;
        }
コード例 #6
0
        /// <summary>
        /// Look through all the import extensions to see if any of them want access to 
        ///   the service reference's extension files.  They tell us this by implementing
        ///   the interface IWcfReferenceReceiveContextInformation.
        /// </summary>
        /// <param name="svcMapFile"></param>
        /// <param name="serviceProviderForImportExtensions"></param>
        /// <param name="wsdlImportExtensions"></param>
        /// <param name="policyImportExtensions"></param>
        internal static void ProvideImportExtensionsWithContextInformation(SvcMapFile svcMapFile, IServiceProvider serviceProviderForImportExtensions, IEnumerable<IWsdlImportExtension> wsdlImportExtensions, IEnumerable<IPolicyImportExtension> policyImportExtensions)
        {
            // Only make this copy if we need to (not the mainline case)
            Dictionary<string, byte[]> extensionFileContents = null;

            foreach (IWsdlImportExtension wsdlImportExtension in wsdlImportExtensions)
            {
                System.Web.Compilation.IWcfReferenceReceiveContextInformation receiveContext =
                    wsdlImportExtension as System.Web.Compilation.IWcfReferenceReceiveContextInformation;
                if (receiveContext != null)
                {
                    if (extensionFileContents == null)
                    {
                        extensionFileContents = CreateDictionaryOfCopiedExtensionFiles(svcMapFile);
                    }
                    receiveContext.ReceiveImportContextInformation(
                        extensionFileContents,
                        serviceProviderForImportExtensions);
                }
            }
            foreach (IPolicyImportExtension policyImportExtension in policyImportExtensions)
            {
                System.Web.Compilation.IWcfReferenceReceiveContextInformation receiveContext =
                    policyImportExtension as System.Web.Compilation.IWcfReferenceReceiveContextInformation;
                if (receiveContext != null)
                {
                    if (extensionFileContents == null)
                    {
                        extensionFileContents = CreateDictionaryOfCopiedExtensionFiles(svcMapFile);
                    }
                    receiveContext.ReceiveImportContextInformation(
                        extensionFileContents,
                        serviceProviderForImportExtensions);
                }
            }
        }
コード例 #7
0
        /// <summary>
        /// Create an appropriate WsdlImporter for the generator
        /// </summary>
        /// <param name="svcMapFile"></param>
        /// <param name="toolConfiguration"></param>
        /// <param name="targetCompileUnit"></param>
        /// <param name="codeDomProvider"></param>
        /// <param name="targetNamespace"></param>
        /// <param name="typeLoader"></param>
        /// <param name="targetFrameworkVersion">Targetted Framework version number</param>
        /// <param name="importErrors"></param>
        /// <param name="typedDataSetSchemaImporterExtension"></param>
        /// <returns></returns>
        protected static WsdlImporter CreateWsdlImporter(SvcMapFile svcMapFile,
                                                      System.Configuration.Configuration toolConfiguration,
                                                      CodeCompileUnit targetCompileUnit,
                                                      System.CodeDom.Compiler.CodeDomProvider codeDomProvider,
                                                      string targetNamespace,
                                                      IServiceProvider serviceProviderForImportExtensions,
                                                      IContractGeneratorReferenceTypeLoader typeLoader,
                                                      int targetFrameworkVersion,
                                                      IList<ProxyGenerationError> importErrors,
                                                      System.Type typedDataSetSchemaImporterExtension)
        {
            List<MetadataSection> metadataSections = CollectMetadataDocuments(svcMapFile.MetadataList, importErrors);

            WsdlImporter importer = null;

            ClientOptions.ProxySerializerType serializerType = svcMapFile.ClientOptions.Serializer;
            if (serializerType == ClientOptions.ProxySerializerType.Auto && ContainsHttpBindings(metadataSections))
            {
                // NOTE: HTTP Get/Post binding indicates an old web service. We use XmlSerializer to prevent generating dup classes.
                // Please check devdiv 
                serializerType = ClientOptions.ProxySerializerType.XmlSerializer;
            }

            if (toolConfiguration != null)
            {
                ServiceModelSectionGroup serviceModelSection = ServiceModelSectionGroup.GetSectionGroup(toolConfiguration);

                if (serviceModelSection != null)
                {
                    Collection<IWsdlImportExtension> wsdlImportExtensions = serviceModelSection.Client.Metadata.LoadWsdlImportExtensions();
                    Collection<IPolicyImportExtension> policyImportExtensions = serviceModelSection.Client.Metadata.LoadPolicyImportExtensions();

                    // If we have specified a specific serializer to use, we remove
                    // the other serializer...
                    switch (serializerType)
                    {
                        case ClientOptions.ProxySerializerType.DataContractSerializer:
                            RemoveExtension(typeof(XmlSerializerMessageContractImporter), wsdlImportExtensions);
                            break;
                        case ClientOptions.ProxySerializerType.XmlSerializer:
                            RemoveExtension(typeof(DataContractSerializerMessageContractImporter), wsdlImportExtensions);
                            break;
                        case ClientOptions.ProxySerializerType.Auto:
                            break;
                        default:
                            System.Diagnostics.Debug.Fail("Unknown serializer");
                            break;
                    }

                    ProvideImportExtensionsWithContextInformation(svcMapFile, serviceProviderForImportExtensions, wsdlImportExtensions, policyImportExtensions);

                    wsdlImportExtensions.Add(new HttpBindingExtension());

                    // Create Importer...
                    importer = new WsdlImporter(new MetadataSet(metadataSections), policyImportExtensions, wsdlImportExtensions);
                }
            }

            if (importer == null)
            {
                importer = new WsdlImporter(new MetadataSet(metadataSections));
            }

            // DevDiv 124333 - Always add DataContract importer (even if we are in XmlSerializerMode) to 
            // enable importing Fault contracts...
            importer.State.Add(typeof(System.Runtime.Serialization.XsdDataContractImporter),
                           CreateDataContractImporter(svcMapFile.ClientOptions, targetCompileUnit, codeDomProvider, targetNamespace, typeLoader, targetFrameworkVersion, importErrors));

            if (serializerType != ClientOptions.ProxySerializerType.DataContractSerializer)
            {
                importer.State.Add(typeof(System.ServiceModel.Channels.XmlSerializerImportOptions),
                               CreateXmlSerializerImportOptions(svcMapFile.ClientOptions,
                                                                targetCompileUnit,
                                                                codeDomProvider,
                                                                targetNamespace,
                                                                typedDataSetSchemaImporterExtension));
            }

            // Read the UseSerializerForFaults from Reference.svcmap, create a FaultImportOptions using this information
            // and pass it to WSDL Importer.
            FaultImportOptions faultOptions = new FaultImportOptions();
            faultOptions.UseMessageFormat = svcMapFile.ClientOptions.UseSerializerForFaults;
            importer.State.Add(typeof(System.ServiceModel.FaultImportOptions), faultOptions);

            // Read the WrappedOptions from Reference.svcmap, create a WrappedOptions using this information
            // and pass it to WSDL Importer.
            WrappedOptions wrappedOptions = new WrappedOptions();
            wrappedOptions.WrappedFlag = svcMapFile.ClientOptions.Wrapped;
            importer.State.Add(typeof(System.ServiceModel.Channels.WrappedOptions), wrappedOptions);

            return importer;
        }
コード例 #8
0
        /// <summary>
        /// Get the appropriate tool configuration for this service reference.
        /// 
        /// If a reference.config file is present, the configuration object returned 
        /// will be the merged view of:
        /// 
        ///    Machine Config
        ///       ReferenceConfig
        ///       
        /// If not reference.config file is present, the configuration object returned
        /// will be a merged view of:
        ///     
        ///     Machine.config
        ///         web.config in application's physical path...
        ///         
        /// </summary>
        /// <param name="mapFile">SvcMapFile representing the service</param>
        /// <returns></returns>
        private System.Configuration.Configuration GetToolConfig(SvcMapFile mapFile, string mapFilePath)
        {
            string toolConfigFile = null;

            if (mapFile != null && mapFilePath != null)
            {
                foreach (ExtensionFile extensionFile in mapFile.Extensions)
                {
                    if (String.Equals(extensionFile.Name, TOOL_CONFIG_ITEM_NAME, StringComparison.Ordinal))
                    {
                        toolConfigFile = extensionFile.FileName;
                    }
                }
            }

            System.Web.Configuration.WebConfigurationFileMap fileMap;
            fileMap = new System.Web.Configuration.WebConfigurationFileMap();

            System.Web.Configuration.VirtualDirectoryMapping mapping;
            if (toolConfigFile != null)
            {
                //
                // If we've got a specific tool configuration to use, we better load that...
                //
                mapping = new System.Web.Configuration.VirtualDirectoryMapping(System.IO.Path.GetDirectoryName(mapFilePath), true, toolConfigFile);
            }
            else
            {
                //
                // Otherwise we fall back to the default web.config file...
                //
                mapping = new System.Web.Configuration.VirtualDirectoryMapping(HostingEnvironment.ApplicationPhysicalPath, true);
            }
            fileMap.VirtualDirectories.Add("/", mapping);

            return System.Web.Configuration.WebConfigurationManager.OpenMappedWebConfiguration(fileMap, "/", System.Web.Hosting.HostingEnvironment.SiteName);

        }
コード例 #9
0
        /// <summary>
        /// Check the result from the code generator.
        /// By default we treat all error messages from WsdlImporter as warnings,
        /// and they will be ignored if valid code has been generated.
        /// We may hit other errors when we parse the metadata files.
        /// Those errors (which are usually because of a bad file) will not be ignored, because the user can fix them.
        /// If the WsdlImporter hasn't generated any code as we expect, we have to consider some of the error messages are fatal.
        /// We collect those messages and report to the user.
        /// </summary>
        /// <param name="referenceDisplayName">The name of the generated reference</param>
        /// <param name="mapFile">Original Map File</param>
        /// <param name="generatedCode">generated code compile unit</param>
        /// <param name="importErrors"></param>
        /// <param name="generatorErrors"></param>
        /// <remarks></remarks>
        private static void VerifyGeneratedCodeAndHandleErrors(
                                            string referenceDisplayName,
                                            SvcMapFile mapFile,
                                            CodeCompileUnit generatedCode,
                                            System.Collections.IEnumerable importErrors,
                                            System.Collections.IEnumerable generatorErrors)
        {
            // Check and report fatal error first...
            HandleProxyGenerationErrors(importErrors);
            HandleProxyGenerationErrors(generatorErrors);

            // if there is no fatal error, we expect valid type generated from the process
            //   unless there is no metadata files, or there is a service contract type sharing
            if (mapFile.MetadataList.Count > 0 && mapFile.ClientOptions.ServiceContractMappingList.Count == 0)
            {
                if (!IsAnyTypeGenerated(generatedCode))
                {
                    StringBuilder collectedMessages = new StringBuilder();

                    // merge error messages
                    CollectErrorMessages(importErrors, collectedMessages);
                    CollectErrorMessages(generatorErrors, collectedMessages);

                    throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, WCFModelStrings.ReferenceGroup_FailedToGenerateCode, referenceDisplayName, collectedMessages.ToString()));
                }
            }
        }