C# XsdDataContractExporter不会编译具有元素的Xsd架构

C# XsdDataContractExporter不会编译具有元素的Xsd架构,c#,wcf,xsd,wsdl,C#,Wcf,Xsd,Wsdl,我有一个带有basicHttpBinding端点的WCF服务。其中一个数据协定中包含的类型之一实现了IXmlSerializable,并包含一个XmlSchemaProvider,该XmlSchemaProvider返回嵌入程序集中的Xsd文件的内容。当我在浏览器中点击端点时,Wsdl生成失败,XmlSchemaException:属性未声明。编译嵌入式Xsd文件时出现问题 我做了一些研究,发现DataContractSerializer和XsdDataContractExporter不支持所有

我有一个带有basicHttpBinding端点的WCF服务。其中一个数据协定中包含的类型之一实现了IXmlSerializable,并包含一个XmlSchemaProvider,该XmlSchemaProvider返回嵌入程序集中的Xsd文件的内容。当我在浏览器中点击端点时,Wsdl生成失败,XmlSchemaException:属性未声明。编译嵌入式Xsd文件时出现问题

我做了一些研究,发现DataContractSerializer和XsdDataContractExporter不支持所有可序列化类型。我怀疑这种行为在这里起作用,因为嵌入式Xsd包含一个必需的属性

我还查看了XsdDataContractExporter代码,发现get_模式在返回之前编译导入的模式集,这就是失败的地方

作为一种解决方法,我修改了WCF服务以使用XmlSerializer而不是DataContractSerializer,Wsdl生成OK。以前有人经历过这种行为吗?想法

下面是一个控制台应用程序和示例Xsd,它将再现错误

using System;
using System.Resources;
using System.Runtime.Serialization;
using System.Xml;
using System.Xml.Schema;
using System.Xml.Serialization;

namespace SchemaCompiler
{
    public class Program
    {
        static void Main()
        {
            var exporter = new XsdDataContractExporter();

            if (!exporter.CanExport(typeof(Foo)))
                return;

            exporter.Export(typeof(Foo));

            // The following line will throw XmlSchemaException: The 'http://www.w3.org/XML/1998/namespace:lang' attribute is not declared.
            var schemaSet = exporter.Schemas;   

            Console.WriteLine(schemaSet.IsCompiled);
        }

        [Serializable]
        [XmlSchemaProvider("GetSchema")]
        public class Foo : IXmlSerializable
        {
            private static XmlSchema _xmlSchema;

            public String Bar { get; set; }
            public String Language { get; set; }

            public static XmlQualifiedName GetSchema(XmlSchemaSet schemaSet)
            {
                var type = typeof(Foo);

                var xsdFileStream = type.Assembly.GetManifestResourceStream(type, "Foo.xsd");
                if (xsdFileStream == null) throw new MissingManifestResourceException(
                        "The embedded resource Foo.xsd was not found. For more information, http://support.microsoft.com/kb/319292");

                _xmlSchema = XmlSchema.Read(xsdFileStream, null);
                schemaSet.Add(_xmlSchema);

                return new XmlQualifiedName(type.Name, "http://tempuri.org/Foo.xsd");
            }

            #region IXmlSerializable Members

            public XmlSchema GetSchema()
            {
                return _xmlSchema;
            }

            public void ReadXml(XmlReader reader)
            {
                throw new NotImplementedException();
            }

            public void WriteXml(XmlWriter writer)
            {
                throw new NotImplementedException();
            }

            #endregion
        }
    }
}
下面是需要嵌入到程序集中的示例Xsd文件:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="Foo" xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://tempuri.org/Foo.xsd" elementFormDefault="qualified">
  <xs:import namespace="http://www.w3.org/XML/1998/namespace" />
  <xs:complexType name="Foo" mixed="false">
    <xs:sequence>
      <xs:element minOccurs="1" maxOccurs="unbounded" name="Value">
        <xs:complexType>
          <xs:simpleContent>
            <xs:extension base="xs:string">
              <xs:attribute ref="xml:lang" use="required" />
            </xs:extension>
          </xs:simpleContent>
        </xs:complexType>
      </xs:element>
    </xs:sequence>
  </xs:complexType>
</xs:schema>

你的分析可能是正确的。但是错误消息抱怨的是一个未声明的属性,而不是一个不受支持的构造,所以我想知道是否还有其他解释

如果使用您的模式文档的软件知道在哪里可以找到名称空间的模式文档,那么您的模式文档应该是良好的http://www.w3.org/XML/1998/namespace. 但我所熟悉的大多数XSD软件都不具备该名称空间的内置知识。我想知道如果您将导入更改为以下内容,您的初始设置是否会工作得更好:

<xs:import namespace="http://www.w3.org/XML/1998/namespace" 
           schemaLocation="http://www.w3.org/2009/01/xml.xsd"/>
注意:这是一个很长的故事,因此您可能更喜欢仅用于测试,当然对于严肃的工作,您可以为XML名称空间制作模式文档的本地副本。示例中给出了URI,并指向您的本地副本