简体   繁体   English

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

[英]C# : WCF Service with IXMLSerializable member turns into DataSet

.NET 。净

I have a web service, one of the data members of a message implements IXmlSerializable, when I do "Add Service Reference" that member becomes a DataSet. 我有一个Web服务,消息的一个数据成员实现IXmlSerializable,当我执行“添加服务引用”时,该成员成为DataSet。

I am trying to pass a serialized Expression<TDelegate> as a parameter to the web service. 我试图将序列化的Expression<TDelegate>作为参数传递给Web服务。

Q: How do I make a DataSet out of the IXmlSerializable instance on the client side? 问:如何从客户端的IXmlSerializable实例中创建DataSet

I realize this is an older question, but for future readers here is what I discovered: 我意识到这是一个较老的问题,但对于未来的读者来说,这是我发现的:

Objects that implement IXmlSerializable need to have a schema defined in order for them to work with the wsdl, otherwise the .Net framework doesn't know how to define the contract because the serialization is custom. 实现IXmlSerializable对象需要定义一个模式,以便它们与wsdl一起使用,否则.Net框架不知道如何定义合同,因为序列化是自定义的。

To specify the schema you are not supposed to use the GetSchema method in the IXmlSerializable interface, rather use the XmlSchemaProvider attribute ( msdn link ). 要指定模式,您不应在IXmlSerializable接口中使用GetSchema方法,而是使用XmlSchemaProvider属性( msdn链接 )。 You can read more about in Microsoft's article Enrich Your XML Serialization With Schema Providers In The .NET Framework inthe schema providers section. 您可以在Microsoft的文章中了解有关在.NET Framework中使用架构提供程序进行XML序列化的文章,请参阅架构提供程序部分。

You can find examples on both the XmlSchemaProvider attribute page and the article, I recommend storing your schemas in .xsd files and reading them in like in the examples. 您可以在XmlSchemaProvider属性页面和文章中找到示例,我建议将您的模式存储在.xsd文件中,并在示例中读取它们。 Writing the schema through code is cumbersome at best. 通过代码编写模式充其量是麻烦的。

Once I implemented the schema provider the serialization worked as expected. 实现模式提供程序后,序列化按预期工作。 If your WCF service is IIS hosted refer to this question on how to get the proper IIS directory via reflection Can I use reflection to find the bin/[Configuration] folder in ASP.NET instead of the asp temporary folder . 如果您的WCF服务是IIS托管,请参阅此问题,了解如何通过反射获取正确的IIS目录。 我可以使用反射来查找ASP.NET中的bin / [Configuration]文件夹而不是asp临时文件夹

Example from the Microsoft article: 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;
    } 

    ...
}

In general, custom serialization (via IXmlSerializable ) over either SOAP or WCF is a bad idea. 通常,通过SOAP或WCF进行自定义序列化(通过IXmlSerializable )是一个坏主意。 If you are using assembly-sharing with WCF (ie rather than proxy generation, you ship the DTO assembly to the client) then it can work, but it still violates SOA/mex etc. Actually, I'm surprised it doesn't just give you XmlElement or similar, but heh! 如果你正在使用与WCF的程序集共享(即代替代理生成,你将DTO程序集发送到客户端)那么它可以工作,但它仍然违反SOA / mex等。实际上,我很惊讶它不仅仅是给你XmlElement或类似的,但是嘿!

I would simply map your existing ( IXmlSerializable ) object model into simple types that can use the standard serialization (ie no IXmlSerializable ). 我只是将现有的( IXmlSerializable )对象模型映射到可以使用标准序列化的简单类型(即没有IXmlSerializable )。

BTW; BTW; have you looked at ADO.NET Data Services? 你看过ADO.NET数据服务吗? This already handles Expression over the wire (although not as a value). 这已经通过线路处理Expression (虽然不作为值)。 For passing as values, MetaLinq . 对于作为值传递, MetaLinq

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM