Преобразование производного класса в базовый класс для сериализации WCF - PullRequest
4 голосов
/ 13 сентября 2011

У меня есть два класса ...

[Serializable]
[DataContract]
public class A
{
    [DataMember]
    public string _a                                   { get; set; }
    [DataMember]
    public bool _b                                     { get; set; }
}

[Serializable]
public class B : A
{
    [NonSerialized]
    [XmlIgnore] 
    private C _c;
}

... и у меня есть служба WCF:

public interface IClient
{

    [ServiceKnownType(typeof(A))]
    [OperationContract(IsOneWay = true)]
    void Somefunction(List<A> listofA);
}

Мне нужно отправить список A клиенту, но у меня есть только список B. Мне плевать на поле "_c". Я бы подумал, что это так просто, как:

List<A> listofA = new List<A>();

foreach (B instanceofb in somestore.Values)
{
    listofA.Add((A)instanceofb);
}

Client.Somefunction(listofA);

Но производный тип объекта хранится в экземпляре базового типа в списке. WCF, кажется, пытается десериализовать и завершиться неудачей, потому что C не сериализуем (хотя я пометил его как проигнорированный). Я не получаю ответа на стороне клиента, а метод на стороне сервера просто проваливается.

Но я могу создать и отправить (и получить на клиенте) тип A, хотя:

List<A> listofA = new List<A>() { new A() };
Client.Somefunction(listofA);

Есть ли какой-нибудь способ, кроме кропотливого (который работает):

public A Convert(B _instanceofb)
{
  A _instanceofA = new A();
  A._a = _instanceofb._a;
  A._b = _instanceofb._b;
  return A;
}

и ..

List<A> listofA = new List<A>();

foreach (B instanceofb in somestore.Values)
{
    listofA.Add(Convert(instanceofb));
}

Client.Somefunction(listofA);

1 Ответ

1 голос
/ 13 сентября 2011

Если ваши объекты являются экземплярами B, они всегда будут сериализованы как экземпляры B - это точка сериализации. Если вы хотите игнорировать _c, попробуйте это:

[DataContract]
public class B : A
{
    private C _c;
}

Если класс помечен DataContract, сериализуются только свойства / поля, помеченные DataMember - я не уверен, как Serializable работает вместе с родителем, используя DataContract.

Вы также должны использовать это, чтобы сообщить службе и клиенту, что B можно использовать:

public interface IClient
{
    [ServiceKnownType(typeof(B))]
    [OperationContract(IsOneWay = true)]
    void Somefunction(List<A> listofA);
}

Если вы хотите отправлять только A экземпляров, вы должны создать A экземпляров, а не B экземпляров - в вашем сценарии это действительно означает преобразование.

...