C#:具有 IXMLSerialized 成员的 WCF 服务变成数据集

发布于 2024-08-05 23:14:43 字数 256 浏览 5 评论 0原文

.NET

我有一个 Web 服务,消息的数据成员之一实现了 IXmlSerialized,当我执行“添加服务引用”时,该成员变成了数据集。

我试图将序列化的 Expression 作为参数传递给 Web 服务。

:如何在客户端使用 IXmlSerialized 实例创建 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.

I am trying to pass a serialized Expression<TDelegate> as a parameter to the web service.

Q: How do I make a DataSet out of the IXmlSerializable instance on the client side?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

梦晓ヶ微光ヅ倾城 2024-08-12 23:14:43

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

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

要指定架构,不应在 IXmlSerialized 接口中使用 GetSchema 方法,而应使用 XmlSchemaProvider 属性 (msdn 链接)。您可以在 Microsoft 的文章 Enrich Your XML Serialization With Schema Providers In The . NET Framework 中的架构提供程序部分。

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

一旦我实现了模式提供程序,序列化就会按预期工作。如果您的 WCF 服务是 IIS 托管的,请参阅此问题,了解如何通过反射获取正确的 IIS 目录 我可以使用反射来查找 ASP.NET 中的 bin/[Configuration] 文件夹而不是 asp 临时文件夹

来自 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;
    } 

    ...
}

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.

To specify the schema you are not supposed to use the GetSchema method in the IXmlSerializable interface, rather use the XmlSchemaProvider attribute (msdn link). You can read more about in Microsoft's article Enrich Your XML Serialization With Schema Providers In The .NET Framework inthe schema providers section.

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. 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.

Example from the Microsoft article:

[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;
    } 

    ...
}
傾旎 2024-08-12 23:14:43

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

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

顺便提一句;您看过 ADO.NET 数据服务吗?这已经通过线路处理Expression(尽管不是作为值)。对于作为值传递,MetaLinq

In general, custom serialization (via IXmlSerializable) over either SOAP or WCF is a bad idea. If you are using assembly-sharing with WCF (i.e. 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!

I would simply map your existing (IXmlSerializable) object model into simple types that can use the standard serialization (i.e. no IXmlSerializable).

BTW; have you looked at ADO.NET Data Services? This already handles Expression over the wire (although not as a value). For passing as values, MetaLinq.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文