C #: служба WCF с членом IXMLSerializable превращается в набор данных - PullRequest
8 голосов
/ 21 сентября 2009

.NET

У меня есть веб-сервис, один из членов данных сообщения реализует IXmlSerializable, когда я делаю «Добавить ссылку на сервис», этот элемент становится DataSet.

Я пытаюсь передать сериализованный Expression<TDelegate> в качестве параметра веб-службе.

Q: Как сделать DataSet из IXmlSerializable экземпляра на стороне клиента?

Ответы [ 2 ]

10 голосов
/ 19 апреля 2010

Я понимаю, что это старый вопрос, но для будущих читателей вот что я обнаружил:

Объекты, которые реализуют IXmlSerializable, должны иметь определенную схему, чтобы они могли работать с wsdl, в противном случае .Net Framework не знает, как определить контракт, потому что сериализация является пользовательской.

Чтобы указать схему, которую вы не должны использовать метод GetSchema в интерфейсе IXmlSerializable, используйте атрибут XmlSchemaProvider ( msdn link ). Подробнее об этом можно прочитать в статье Microsoft Обогатите сериализацию XML с помощью поставщиков схем. В разделе .NET Framework в разделе поставщиков схем.

Примеры можно найти как на странице атрибутов XmlSchemaProvider, так и в статье, я рекомендую хранить ваши схемы в файлах .xsd и читать их, как в примерах. Написание схемы через код в лучшем случае громоздко.

Как только я реализовал провайдера схемы, сериализация работала как ожидалось. Если ваша служба WCF размещена на IIS, обратитесь к этому вопросу о том, как получить правильный каталог IIS с помощью рефлексии Можно ли использовать рефлексию для поиска папки bin / [Configuration] в ASP.NET вместо временной папки 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;
    } 

    ...
}
4 голосов
/ 22 сентября 2009

Как правило, настраиваемая сериализация (через IXmlSerializable) через SOAP или WCF - плохая идея. Если вы используете совместное использование сборок с WCF (то есть, вместо генерации прокси, вы отправляете сборку DTO клиенту), тогда она может работать, но все равно нарушает SOA / mex и т. Д. На самом деле, я удивлена, что это не просто дать вам XmlElement или подобное, но хе!

Я бы просто отобразил вашу существующую (IXmlSerializable) объектную модель на простых типов, которые могут использовать стандартную сериализацию (т. Е. Нет IXmlSerializable).

КСТАТИ; Вы смотрели на ADO.NET Data Services? Это уже обрабатывает Expression по проводу (хотя и не как значение). Для передачи в качестве значений, MetaLinq .

...