2009-01-28 12 views
7

Bir web servisinden karmaşık bir tür döndürmem gerekiyor ve IMyComplexType arabirimini uygulayan MyComplexType sınıfını oluşturmuştum.Arabirimleri .net webservislerinden döndürmek mümkün mü yoksa yalnızca beton sınıflarını geri alabilir mi?

[WebMethod] 
public IMyComplexType GetMyComplexType() 
{ 
    IMyComplexType myCt = new MyComplexType(); 
    ... 
    return myCt; 
} 

Her şey tamam derler ama webservice çalıştırdığınızda aşağıdaki gibi bir istisna atar:

System.NotSupportedException: Cannot serialize interface MyWebService.IMyComplexType. 

mi Şimdi benim webservice ben şöyle IMyComplexType uygulayan bir nesne döndürmesi gerekir bir yöntem var Bu tasarım tarafından veya bir şey eksik. Buna izin vermek için sınıfımı veya arayüzümü bir şekilde dekore edebilir miyim? Tüm arayüzleri elimden çıkarmak ve bunu sadece .net web servisleri ile yapabilmek için somut ve belki de soyut temel sınıflarla çalışmak zorunda mıyım?

Düzenleme:

bu ben getirilmeye çalışıyorum arayüz:

public interface ICustomer 
{ 
    long Id {get; set;} 
    string Name {get; set;} 
    string EmailAddress {get; set;} 
} 

cevap

0

Bir süre oldu, ama ben size arayüzleri ISerializable uzatmak yapmak ve tüm iyi olmalıdır sadece ihtiyaç inanıyoruz.

+0

Bu sırayla ISerializable arabirimini tüm sınıflarımda uygulamamı gerektiriyordu - buna rağmen bunu yapmak zorunda kalmadan serileştirmeyi umuyordum. Sadece halka mallara ihtiyacım var. Arayüzleri ortadan kaldırmak ve sadece beton sınıflarını kullanmak iyi çalışıyor ama bu en iyi uygulama mı? – Fadeproof

0

ISerializable kodunu uygulamanıza gerek yoktur - sadece arayüzü Serializable özniteliği ile işaretlemeniz gerekir. Arayüzü uygulamak istiyorsanız, her şeyden önce, arayüzün nasıl serileştirildiği konusunda ince ayarlı kontrol sağlayacaktır. Ancak, varsayılan uygulamanın iyi olması gerektiğini düşünürdüm. Ayrıca, tüm arayüz elemanlarının da seri hale getirilebildiğinden emin olun.

[Düzenle] Düzgün düşünmüyordum bile - bir iterface'i seri hale getirmeye çalışırken ISerializable'u uygulayabilmenin hiçbir yolu yoktur. ISerializable'un uygun olacağı yer, arabirim tarafından gösterilen özel serileştirme gerektiren özel türlerde olurdu.

+0

Serializable özniteliğini arayüzlere yerleştiremez - yalnızca sınıflar, enumlar vb. Önereceğin başka bir şey var mı? Herhangi bir özel seri hale getirme gereksinimim yok. Sadece işleri düzgün bir şekilde ortaya çıkarmaya çalışıyorum - arayüzler aracılığıyla ve somut olmayan tiplerle. Bu ws ile imkansız mı? – Fadeproof

+0

Arayüzünüzdeki türlerden bir tanesi seri hale getirilemez gibi geliyor - Yazılarınızı düzenleyebilir ve arayüz için kod ekleyebilir misiniz? –

+0

Tamam. Arayüz eklendi. ISerializable'ı uygulamadan bunu yapmanın bir yolu var mı, sadece bunun gibi bir seri haline getirilmemesini ve özel ihtiyaçların olmasını istiyor muyum? – Fadeproof

2

Kısa yanıt hayır, bir WebService aracılığıyla bir arabirim döndüremezsiniz.

Uzun cevap, istediğiniz davranışı elde edebilmenizdir, ancak biraz rahatsız edici. Çözüm, ikili serileştirme kullanmaktır. Böylece, türünüzü baytlara serileştirirsiniz, web yönteminin bir dizi bayt getirmesini sağlayın ve diğer tarafta baytları karmaşık türünüze geri gönderirsiniz. Örneğin

için

[WebMethod] 
public byte[] GetMyComplexType() 
{ 

    IMyComplexType myCt = new MyComplexType(); 
    ... 

    MemoryStream stream = new MemoryStream(); 
    IFormatter fmt = new BinaryFormatter(); 
    fmt.Serialize(stream, myCt); 
    stream.Flush(); 
    byte[] bytes = stream.ToArray(); 
    stream.Close(); 

    return bytes; 
} 

Sen diğer ucunda her şeyi geri dönüştürmek gerekir.

byte[] bytes = service.GetMyComplexType(); 
MemoryStream stream = new MemoryStream(bytes); 
BinaryFormatter fmt = new BinaryFomatter(); 
MyComplexType myCt = fmt.DeSerialize(stream); 

Genel bir yöntem oluşturarak seri hale getirme işlemini muhtemelen temizleyebilirsiniz. Eklemeliyim ki, istemcideki karmaşık türlere başvurabildiğinizden emin olmanız gerekir.

Arabirimlerinizse, bunları Soyut Sınıflara dönüştürebilir. Ancak, sınıfın yalnızca bir sınıfı devralabildiğiniz için birden çok arabirimi (veya başka bir sınıftan miras almayı) uygulamasını istiyorsanız bu işe yaramaz. İstemcide bazı polimorf davranışlara ihtiyacınız varsa, XmlInclude özniteliğini kullanmanız gerekir.

İlgili konular