2011-05-24 17 views
18

Bir WCF hizmeti oluşturuyorum ve bazı Serileştirme sorunlarıyla ilgili çok fazla sorun yaşıyorum. Belki orada bunu yapmak için sadece 1 yol, ama ben İşte benim örnek kod var o teyit etmek istiyorum:WCF, Arabirim dönüş türü ve bilinen bilgiler

Sözleşmeler

public interface IAtm 
    { 
     [DataMember] 
     double Latitude { get; set; } 

     [DataMember] 
     double Longitude { get; set; } 
    } 

[ServiceContract] 
    public interface IAtmFinderService 
    { 

     [OperationContract] 
     ICollection<IAtm> GetAtms(); 

    } 

Hizmet Uygulaması:

[KnownType(typeof(Atm))] 
[KnownType(typeof(List<Atm>))] 
[ServiceKnownType(typeof(Atm))] 
[ServiceKnownType(typeof(List<Atm>))] 
public class AtmFinderService : IAtmFinderService 
{ 
    public ICollection<IAtm> GetAtms() 
    { 
     return new List<IAtm>() 
      { 
       new Atm() { Latitude = 1, Longitude = 1 }, 
       new Atm() { Latitude = 2, Longitude = 2 } 
      }; 
    } 
} 

Ben tüm katma KnownType ve ServiceKnownType öznitelikleri var, çünkü orada eksik bir şey olduğunu düşündüm .. Şimdi bazı testler yapıyorum. VS'nin otomatik olarak proxy oluşturmasını sağlamak için "hizmet referansı ekle" yöntemini kullanarak bir konsol uygulaması oluşturmayı denedim.

InnerException mesajı 'Tür '' veri sözleşme adıyla ile' WCFTest.Atm oldu: Bu şekilde, ben

object[] GetAtms(); 

diyoruz çalışıyor gibi bir işlevi olsun, ben bu hatayı alıyorum Atm: http: //schemas.datacontract.org/2004/07/WCFTest ' beklenmiyor. Bir DataContractResolver kullanmayı düşünün ya da olmasın bilinen türleri listesine statik bilinen herhangi türde ekleyin -. Örneğin DataContractSerializer geçirilen bilinen türleri listesine ekleyerek KnownTypeAttribute nitelik veya tarafından kullanılarak '.

Çok güzel ... Öyleyse, VS'nin otomatik olarak oluşturulmuş kodunun saçmalık olduğunu düşünüyorum.

[OperationContract] 
     ICollection<Atm> GetAtms(); 

Yani şimdi, ben bir beton türü iade ediyorum: Ben hizmet (ve ilgili tüm sınıflar ve uygulamalar) aşağıdaki değişikliği yaptı. Servis referansını güncelledikten sonra, üyeleri ve eşyalarıyla birlikte Atm sınıfının bir kopyasını oluşturur. Servisi aradıktan sonra, çağrı başarılı olur. Bunun otomatik olarak oluşturulmuş kodla ilgili bazı kötü davranışlar olduğunu düşündüm, bu yüzden çok basit bir ana makine/istemci uygulaması oluşturmayı denedim. Bazı bağlantı noktasını dinleyen bir konsol ana bilgisayarı başlattım ve sonra hizmete çağrı yapmak için ClientBase sınıfını kullanan bir istemci oluşturdum. Aynı davranış ... Hizmetin bir arabirim türünü döndürmesi durumunda, başarısız olur. Beton tipini döndürmek için değiştirirsem işe yarıyor. KnownType öznitelikleriyle ilgili bir sorunum olduğunu düşünüyorum, serileştiricinin işleyemediği bir şey eksik olmalıyım. ama ne olduğunu bilmiyorum.

cevap

36

Tamam, ben, gördüğüm kadarıyla o sorunu düzeltmek başardı bu

Ben bir arabirim ve bir beton sınıfı iade ediyorum beri WCF diğer yandan ne olacağını bilmiyor oldu son. Yani, her şey olabilir. Liste aldığında, kafası karışır.
Bunu yapmanın doğru yolu, gerektiğinde KnownType özniteliklerini eklemekti.
Bu türleri kimin bilmesi gerekiyor? Hizmet uygulaması, onları doğru bir şekilde serileştirmek ve serileştirmek. Bununla birlikte, müşteri, uygulamanın kendisi ile değil, hizmetin arayüzü ile konuşur. Bu nedenle, hizmet uygulamasında KnownType özniteliğinin eklenmesi işe yaramadı
Burada sorun, arabirimlerin KnownType özniteliklerine izin vermemesi, ancak ServiceKnownType özniteliklerine izin vermeleridir.sorunun çözümü hizmeti arayüzü sözleşmesinde beklenen türü ekleme oldu, ve işte, her şey düzeltme için

[ServiceContract] 
    [ServiceKnownType(typeof(Atm))] 
    [ServiceKnownType(typeof(List<Atm>))] 
    public interface IAtmFinderService 
    { 

     [OperationContract] 
     ICollection<IAtm> GetAtms(); 

    } 
+0

+1 Teşekkür Tamam çalışır ve kullanan arayüzleri, ben aynı problem vardı ama sadece eklemek için gerekli Özel PagedList uygulamam için uygulamasının listesi. Benim "T" bir alan nesnesiydi ve benim için doğru şekilde serileştirilmişti. – Jay

İlgili konular