Тип не предоставляется службой WCF - PullRequest
4 голосов
/ 24 марта 2010

У меня есть небольшой тестовый веб-сервис для эмуляции чего-то странного, что я замечаю в реальном приложении. Поскольку демонстрация демонстрирует то же поведение, что и приложение, я буду использовать ее для краткости.

Короче говоря, мой файл интерфейса службы выглядит следующим образом (как вы можете видеть, это служба WCF по умолчанию, созданная VS2008, но я добавил новый открытый метод (GetOtherType ()) и два новых класса внизу (SomeOtherType и SomeComplexType) ) SomeOtherType управляет общим списком типа SomeComplexType

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;

namespace WCFServiceTest
{

    [ServiceContract]
    public interface IService1
    {
        [OperationContract]
        string GetData(int value);

        [OperationContract]
        CompositeType GetDataUsingDataContract(CompositeType composite);

        [OperationContract]
        SomeOtherType GetOtherType();

    }


    [DataContract]
    public class CompositeType
    {
        bool boolValue = true;
        string stringValue = "Hello ";

        [DataMember]
        public bool BoolValue
        {
            get { return boolValue; }
            set { boolValue = value; }
        }

        [DataMember]
        public string StringValue
        {
            get { return stringValue; }
            set { stringValue = value; }
        }
    }

    [DataContract]
    public class SomeOtherType
    {
        public List<SomeComplexType> Items { get; set; }    
    }

    [DataContract]
    public class SomeComplexType
    {

    }
}

Мой сервис реализован следующим образом

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;

namespace WCFServiceTest
{

    public class Service1 : IService1
    {


        #region IService1 Members

        public string GetData(int value)
        {
            throw new NotImplementedException();
        }

        public CompositeType GetDataUsingDataContract(CompositeType composite)
        {
            throw new NotImplementedException();
        }

        #endregion

        #region IService1 Members


        public SomeOtherType GetOtherType()
        {
            throw new NotImplementedException();
        }

        #endregion
    }
}

Проблема, с которой я столкнулся, заключается в том, что, если я включаю ссылку на эту службу в веб-приложение ASP.NET, я не вижу SomeComplexType через intellisense. Ошибка относится к типу или пространству имен не может быть найдено. Тем не менее, SomeOtherType может быть найден (я предполагаю, что тип является возвращаемым типом одного из открытых методов).

Правильно ли я считаю, что не могу предоставить тип из службы WCF, если этот тип не указан в сигнатуре метода одного из моих открытых методов (либо возвращаемого типа, либо аргумента)? Если так, как я смогу перебирать элементы внутри экземпляра SomeOtherType на клиенте?

Большое спасибо, и я надеюсь, что это понятно.

Simon

Ответы [ 5 ]

4 голосов
/ 24 марта 2010

Проблема в том, что если я включить сервисную ссылку на это служба в веб-приложении ASP.NET, Я не могу видеть SomeComplexType через IntelliSense. Ошибка относится к тип или пространство имен не может быть найдено. Тем не менее, SomeOtherType можно найти (Я предполагаю, что тип является возвращением введите один из открытых методов).

Правильно ли я думаю, что не могу разоблачить тип из службы WCF, если этот тип не фигурирует в методе подпись одного из моих публичных методов (либо возвращаемый тип, либо аргумент)? Если Итак, как бы я мог повторить над предметами внутри экземпляра SomeOtherType на клиенте?

Вы абсолютно правы - ваш SomeComplexType никогда не используется ни в одном из методов обслуживания, и он также никогда не помечается как [DataMember] в любом из типов, которые действительно используются в качестве параметров в ваших методах обслуживания. Следовательно, с точки зрения WCF, он не нужен и не будет отображаться в WSDL / XSD для службы.

Как уже указывал Грэм - вы используете SomeComplexType в одном месте:

[DataContract]
public class SomeOtherType
{
    public List<SomeComplexType> Items { get; set; }    
}

но поскольку элемент Items не помечен как [DataMember], он (и, следовательно, используемый им тип) не будет включен в WSDL / XSD вашей службы. Так как Items не помечены как DataMember, они также не будут присутствовать в вашем сериализованном сообщении WCF, поэтому вам никогда не придется перебирать эту коллекцию :-)

Скорее всего, то, что вам действительно нужно, это просто добавить атрибут [DataMember] в ваше свойство Items; затем он будет включен в WSDL / XSD, как и SomeComplexType.

2 голосов
/ 24 марта 2010

Похоже, вам нужен атрибут [DataMember] в свойстве SomeOtherType.Items, т.е.

[DataMember]
public List<SomeComplexType> Items { get; set; }  
1 голос
/ 25 ноября 2011

Мы можем использовать Известный тип в Сервисе, чтобы раскрыть класс и его членов, когда он не используется в подписи контракта операции прямо или косвенно.

1 голос
/ 24 марта 2010

Я совсем не эксперт по этой теме, так что просто как синяк: пустые Контракты с данными отбрасываются WCF? Попробуйте выставить что-нибудь в ComplexDataType (немного int достаточно) и посмотрите, изменит ли это что-либо.

Кроме того, я полагаю, что вы можете проверить доступность типа с помощью встроенного wcftestclient (для этого необходимо включить обмен метаданными).

0 голосов
/ 11 октября 2016

Для таких типов, где вы просто хотите, чтобы он был доступен на стороне клиента, даже если он не используется, нижеприведенный класс атрибутов удобен для того, чтобы сделать его доступным на стороне клиента.

    [KnownType(typeof(SomeComplexType))]
...