C#:带有IXMLSerializable成员的WCF服务变为DataSet

时间:2009-09-21 19:47:57

标签: c# .net wcf dataset ixmlserializable

.NET

我有一个Web服务,当我执行“添加服务引用”时,该消息的一个数据成员实现IXmlSerializable,该成员成为DataSet。

我正在尝试将序列化的Expression<TDelegate>作为参数传递给Web服务。

问:如何在客户端DataSet实例中生成IXmlSerializable

2 个答案:

答案 0 :(得分:10)

我意识到这是一个较老的问题,但对于未来的读者来说,这就是我发现的:

实现IXmlSerializable的对象需要定义一个模式才能使它们与wsdl一起使用,否则.Net框架不知道如何定义合同,因为序列化是自定义的。

要指定模式,您不应在IXmlSerializable接口中使用GetSchema方法,而是使用XmlSchemaProvider属性(msdn link)。您可以在架构提供商部分的Microsoft文章Enrich Your XML Serialization With Schema Providers In The .NET Framework中阅读更多信息。

您可以在XmlSchemaProvider属性页面和文章中找到示例,我建议您将模式存储在.xsd文件中,并在示例中读取它们。通过代码编写模式充其量是麻烦的。

一旦我实现了架构提供程序,序列化就会按预期工作。如果您的WCF服务是IIS托管的,请参阅此问题,了解如何通过反射Can I use reflection to find the bin/[Configuration] folder in ASP.NET instead of the asp temporary folder获取正确的IIS目录。

Microsoft文章中的示例:

[XmlRoot(ElementName="product_root", DataType="product_type", 
    Namespace="http://SchemaProvider.Example.org/Product.xsd",
    IsNullable = false)]
[XmlSchemaProviderAttribute("GetSchemaFile")]
public class Product : IXmlSerializable
{ 
    public static XmlSchemaComplexType GetSchemaFile(
        System.Xml.Schema.XmlSchemaSet xs)
    {
        string xsdFile = Directory.GetCurrentDirectory() + 
            "\\Product.xsd";
        XmlSerializer schemaSerializer = 
            new XmlSerializer(typeof(XmlSchema));
        XmlSchema schema = 
            (XmlSchema)schemaSerializer.Deserialize(
                XmlReader.Create(xsdFile));
        xs.Add(schema);

        // target namespace
        string tns = "http://SchemaProvider.Example.org/Product.xsd";  
        XmlQualifiedName name = 
            new XmlQualifiedName("product_type", tns);
        XmlSchemaComplexType productType = 
            (XmlSchemaComplexType) schema.SchemaTypes[name];

        return productType;
    } 

    ...
}

答案 1 :(得分:4)

通常,通过SOAP或WCF进行自定义序列化(通过IXmlSerializable)是一个坏主意。如果你正在使用与WCF的程序集共享(即代替代理生成,你将DTO程序集发送到客户端)那么它可以工作,但它仍然违反SOA / mex等。实际上,我很惊讶它不仅仅是给你XmlElement或类似的,但是嘿!

我只是将您现有的(IXmlSerializable)对象模型映射到可以使用标准序列化的简单类型(即没有IXmlSerializable)。

顺便说一句;你看过ADO.NET数据服务吗?这已经通过网络处理Expression(虽然不是一个值)。作为值传递,MetaLinq