[英]C# : WCF Service with IXMLSerializable member turns into DataSet
。净
我有一个Web服务,消息的一个数据成员实现IXmlSerializable,当我执行“添加服务引用”时,该成员成为DataSet。
我试图将序列化的Expression<TDelegate>
作为参数传递给Web服务。
问:如何从客户端的IXmlSerializable
实例中创建DataSet
?
我意识到这是一个较老的问题,但对于未来的读者来说,这是我发现的:
实现IXmlSerializable
对象需要定义一个模式,以便它们与wsdl一起使用,否则.Net框架不知道如何定义合同,因为序列化是自定义的。
要指定模式,您不应在IXmlSerializable接口中使用GetSchema方法,而是使用XmlSchemaProvider
属性( msdn链接 )。 您可以在Microsoft的文章中了解有关在.NET Framework中使用架构提供程序进行XML序列化的文章,请参阅架构提供程序部分。
您可以在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;
}
...
}
通常,通过SOAP或WCF进行自定义序列化(通过IXmlSerializable
)是一个坏主意。 如果你正在使用与WCF的程序集共享(即代替代理生成,你将DTO程序集发送到客户端)那么它可以工作,但它仍然违反SOA / mex等。实际上,我很惊讶它不仅仅是给你XmlElement
或类似的,但是嘿!
我只是将现有的( IXmlSerializable
)对象模型映射到可以使用标准序列化的简单类型(即没有IXmlSerializable
)。
BTW; 你看过ADO.NET数据服务吗? 这已经通过线路处理Expression
(虽然不作为值)。 对于作为值传递, MetaLinq 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.