![](/img/trans.png)
[英]C#: copy base class collection objects into derived class objects
[英]Silverlight WCF: consuming a collection of derived objects as a collection of base class results in a NetDispatcherFaultException
類的層次結構很簡單:
在第一個PCL上:
namespace ClassLibrary1
{
[DataContract]
public class BaseClass
{
[DataMember]
public string BaseString { get; set; }
}
}
在第二個PCL上(當然,引用第一個...)
namespace ClassLibrary2
{
[DataContract]
public class Derived : BaseClass
{
[DataMember]
public string DerivedString { get; set; }
}
}
服務(在WebApp上):
namespace SilverlightApplication1.Web
{
[ServiceContract(Namespace = "")]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
[KnownType(typeof(Derived))]
public class Service1
{
[OperationContract]
public List<BaseClass> GetSomething()
{
var data = new List<BaseClass>();
data.Add(new Derived());
return data;
}
}
}
現在,服務引用不會將ServiceKnownType屬性添加到reference.cs文件。 和產生的錯誤:
格式化程序嘗試反序列化消息時引發異常:嘗試反序列化參數:GetQueueItemsResult時發生錯誤。 InnerException消息是“元素” http://schemas.datacontract.org/2004/07/XXX_BASE_CLASS ,其中包含“ http://schemas.datacontract.org/2004/07/XXX_DERIVED_CLASS ”數據協定的數據。 解串器不知道任何映射到該合同的類型。 將與“ DERIVED_CLASS”相對應的類型添加到已知類型的列表中-例如,通過使用KnownTypeAttribute屬性或將其添加到傳遞給DataContractSerializer的已知類型的列表中。 有關更多詳細信息,請參見InnerException。
[更新]當然會在客戶端引發錯誤。 服務器端會返回正確的值,但客戶端無法正確解析它們。 Fiddler說服務器返回了0個字節。 但實際上是客戶無法反序列化數據。
我需要一些方法來告訴運行時反序列化器如何將BaseClass反序列化為實際傳輸的類型。 [/更新]
您需要告訴DataContractSerializer將序列化的序列化為基類。 為此,您需要在派生類上使用Name屬性來闡明DataContract:
[DataContract(Name="BaseClass")]
public class Derived : BaseClass
[DataMember]
public string DerivedString { get; set; }
}
我100%不確定是否需要將Derived
聲明為KnownType
我強烈懷疑您這樣做。
另外,您正在Service類上使用KnownType-就我的理解,您應該在此處使用ServiceKnownType。 通常,您可以選擇:
一種。 在對象類上使用KnownType。
b。 在服務合同上使用ServiceKnownType(通常在服務的接口代理上)。
我喜歡后來的b。 因為它將所有KnownTypes集中在一個地方-一個。 讓他們在每個對象的所有代碼中進行分類-但這只是個人喜好。
如何在DataContract
類型定義中設置KnownType屬性,使反序列化程序在運行時能夠找到正確的類型,這是否解決了問題?
namespace ClassLibrary1
{
[DataContract]
[KnownType(typeof(BaseClass))]
[KnownType(typeof(Derived))]
public class BaseClass
{
[DataMember]
public string BaseString { get; set; }
}
}
namespace ClassLibrary2
{
[DataContract]
[KnownType(typeof(BaseClass))]
[KnownType(typeof(Derived))]
public class Derived : BaseClass
{
[DataMember]
public string DerivedString { get; set; }
}
}
老實說,我不確定您是否必須在兩個DataContracts上設置屬性,還是只在派生類型上設置屬性,還是在基類型上設置屬性。
這似乎是Silverlight /客戶端代碼生成器中的錯誤。
如果您有返回“基類”集合的服務,silverlight客戶端代碼生成器(添加服務引用)將無法將派生類型添加為ServiceKnownType / KnowType或在生成的客戶端代碼上添加任何內容。
我們當前使用的解決方案(直到我們完全放棄SL)是將ServiceKnownType聲明手動復制粘貼到所有派生類型的生成代碼中-每次生成代碼時。
真惡心! 但是有效。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.