Tôi muốn dịch vụ của tôi để có thể chấp nhận và trả lại các loại có nguồn gốc từ BaseType
mà không thực sự biết những gì các loại sẽ được. Tôi đã gần như có một giải pháp bằng cách sử dụng tùy chỉnh DataContractResolver
dựa trên SharedTypeResolver from this excellent blog post.Deserialize các loại có nguồn gốc trong WCF dịch vụ như các loại cơ sở nhưng giữ lại thông tin loại
Phần còn thiếu của câu đố là các loại dịch vụ của tôi sẽ xử lý có thể không được chia sẻ và được biết đến với dịch vụ nhưng tôi vẫn muốn chấp nhận chúng và nhận thức được loại nên có. Tôi đã đưa ra ví dụ sau về một dịch vụ hoạt động như một chồng. Bạn có thể đẩy và bật bất kỳ loại nào có nguồn gốc từ BaseType
miễn là bạn sử dụng SharedTypeResolver
và các loại được chia sẻ giữa máy khách và máy chủ.
[DataContract]
public class BaseType
{
[DataMember]
public string SomeText { get; set; }
public override string ToString()
{
return this.GetType().Name + ": " + this.SomeText;
}
}
[DataContract]
public class DerivedType : BaseType
{
[DataMember]
public int SomeNumber { get; set; }
public override string ToString()
{
return base.ToString() + ", " + this.SomeNumber;
}
}
[ServiceContract]
public interface ITypeStack
{
[OperationContract]
void Push(BaseType item);
[OperationContract]
BaseType Pop();
}
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
public class TypeStackService : ITypeStack
{
private Stack<BaseType> stack = new Stack<BaseType>();
public void Push(BaseType item)
{
this.stack.Push(item);
}
public BaseType Pop()
{
return this.stack.Pop();
}
}
Đây rõ ràng là một ví dụ đơn giản về sự cố tôi đang gặp phải. Một khách hàng có thể khá vui vẻ đẩy và bật BaseType
hoặc DerivedType
vì cả khách hàng và máy chủ đều biết về họ, nhưng nếu khách hàng đẩy UnsharedType
mà dịch vụ không biết tôi gặp lỗi như bạn mong đợi.
Các định dạng ném một ngoại lệ khi cố gắng deserialize thông điệp : Có lỗi trong khi cố gắng deserialize tham số http://tempuri.org/:item. Thông báo InnerException là 'Lỗi ở dòng 1 vị trí 316. Yếu tố' http://tempuri.org/:item 'chứa dữ liệu từ loại bản đồ với tên' TestWcfClient, Phiên bản = 1.0.0.0, Văn hóa = trung lập, PublicKeyToken = null: TestWcfClient.UnsharedType ' . Các deserializer không có kiến thức về bất kỳ loại bản đồ để tên này. Cân nhắc việc thay đổi cách triển khai phương thức ResolveName trên DataContractResolver của bạn để trả về giá trị không null cho tên 'TestWcfClient.UnsharedType' và không gian tên 'TestWcfClient, Version = 1.0.0.0, Culture = neutral, PublicKeyToken = null'. ' . Vui lòng xem InnerException để biết thêm chi tiết.
suy nghĩ hiện tại của tôi là thêm IExtensibleDataObject
để BaseType
để giữ các giá trị từ một loại không chia sẻ và đưa ra một loại không chia sẻ giống như BaseType
với dịch vụ trên deserialization khi một mục được đẩy; điều ngược lại sẽ cần phải xảy ra khi một vật phẩm xuất hiện. Tôi chỉ không chắc chắn làm thế nào để đi về nó. suy nghĩ của tôi cho đến nay về các phương pháp có thể:
- tùy Hơn nữa để
DataContractResolver
mà có thể liên quan đến mộtTypeDelegator
- Sử dụng
IDataContractSurrogate
ở vị trí của một loại không chia sẻ - Bằng cách nào đó giữ lại XML serialized dịch vụ nhận được khi một mục được đẩy , sau đó sử dụng điều này trong thư trả lời khi một mục được xuất hiện
- Sử dụng trình kiểm tra thư để thao tác các thư
Tôi không biết liệu có bất kỳ thứ gì trong số này sẽ hoạt động hay không, những gì sẽ được tham gia hoặc giải pháp tốt nhất là gì. Bạn có?
Bạn sẽ thay đổi các đối tượng trên dịch vụ hay bạn chỉ cần lưu trữ chúng và gửi lại cho khách hàng? – Enes
Chỉ lưu trữ và gửi lại. Tôi cần biết về kiểu cơ sở vì nó có một số thuộc tính mà dịch vụ sử dụng để tác động đến bộ nhớ, nhưng nó chỉ đọc cho đến khi dịch vụ được quan tâm. – batwad