Làm cách nào để trả về loại giao diện trong thông số loại chung từ OperationContracts
trong dịch vụ WCF REST của tôi? Cụ thể hơn, nó hoạt động cho một hoạt động nhưng không phải khi tôi thêm một thao tác thứ hai với một số chung là T
là một giao diện.Loại trả về chung với thông số loại giao diện trong WCF
Tôi đang sử dụng JSON làm định dạng yêu cầu và phản hồi, cho khách hàng không WCF phân tích cú pháp phản hồi JSON cho dữ liệu cần thiết. Tôi không sử dụng SOAP, hoặc WSDL do dịch vụ tạo ra.
giao diện dịch vụ của tôi:
[ServiceContract]
[ServiceKnownType("GetServiceKnownTypes", typeof(ServiceKnownTypesHelper))]
public interface IMyService
{
[WebGet(UriTemplate="count")]
[OperationContract]
IServiceResult<int> GetCount();
[WebGet(UriTemplate="desc")]
[OperationContract]
IServiceResult<string> GetDescription();
[WebGet(UriTemplate="foo")]
[OperationContract]
IServiceResult<IFooData> GetFooData();
// Fails when I invoke either method if I uncomment this operation.
//[WebGet(UriTemplate="bar")]
//[OperationContract]
//IServiceResult<IBarData> GetBarData();
}
tôi rời GetCount()
và GetDescription()
trong ví dụ này chỉ ra rằng hai kết quả chung hoạt động tốt, nhưng rõ ràng họ là loại bê tông. Và thậm chí GetFooData()
hoạt động tốt cho đến khi tôi thêm phương thức thứ hai là IServiceResult<T>
trong đó T
là một giao diện.
Loại trả về GetFooData()
và GetBarData()
không giống nhau, cũng như không phải là các lớp cụ thể triển khai chúng.
Bạn có thể tưởng tượng rằng tôi đã giảm việc thực hiện một bộ xương như tôi không nghĩ rằng việc thực hiện là trung tâm của vấn đề:
#region My service implementation
public class MyService : IMyService
{
public IServiceResult<int> GetCount()
{
return new ServiceResult<int>(42);
}
public IServiceResult<string> GetDescription()
{
return new ServiceResult<string>("Muffins");
}
public IServiceResult<IFooData> GetFooData()
{
return new ServiceResult<IFooData>(new FooData() { Foo = 99 });
}
public IServiceResult<IBarData> GetBarData()
{
return new ServiceResult<IBarData>(new BarData() { Bar = "Elvis was here" });
}
}
#endregion
#region ServiceKnownTypesHelper.GetServiceKnownTypes():
public static class ServiceKnownTypesHelper
{
private static IList<Type> serviceKnownTypes = new List<Type>()
{
typeof(FooData),
typeof(BarData),
typeof(ServiceResult<int>),
typeof(ServiceResult<string>),
typeof(ServiceResult<IFooData>),
typeof(ServiceResult<IBarData>),
};
public static IEnumerable<Type> GetServiceKnownTypes(ICustomAttributeProvider paramIgnored)
{
return serviceKnownTypes;
}
}
#endregion
#region IServiceResult<T> and its concrete implementation:
public interface IServiceResult<T>
{
IList<string> Errors { get; }
T Value { get; set; }
}
[DataContract]
public class ServiceResult<T> : IServiceResult<T>
{
public ServiceResult(T value)
{
this.Value = value;
}
private IList<string> errors = new List<string>();
[DataMember]
public IList<string> Errors
{
get
{
return this.errors;
}
}
[DataMember]
public T Value { get; set; }
}
#endregion
#region IFooData and its concrete implementation:
public interface IFooData
{
int Foo { get; set; }
}
[DataContract]
public class FooData: IFooData
{
[DataMember]
public int Foo { get; set; }
}
#endregion
#region IBarData and its concrete implementation:
public interface IBarData
{
string Bar { get; set; }
}
[DataContract]
public class BarData: IBarData
{
[DataMember]
public string Bar { get; set; }
}
#endregion
Và được thông báo lỗi khi tôi gọi GetBarData()
từ trình duyệt :
Type 'ServiceResult`1[IBarData]' cannot be added to list of known types since another type 'ServiceResult`1[IFooData]' with the same data contract name 'http://schemas.datacontract.org/2004/07/ServiceResultOfanyType' is already present.
phần còn lại của các thông báo lỗi là một cá trích đỏ về va chạm loại bộ sưu tập List<Test>
và Test[]
, mà không phải là trường hợp ở đây.
Rõ ràng, IFooData
và IBarData
không giống nhau và cũng không phải là lớp học triển khai chúng.
Vậy tại sao ServiceResult<IFooData>
và ServiceResult<IBarData>
cả hai đều giải quyết thành ServiceResultOfanyType
?
Tôi có thiếu thứ gì đó hay không có cách nào để sửa lỗi này?
Cho đến nay, giải pháp duy nhất tôi tìm thấy là làm phẳng các kiểu ServiceResult chung thành một nhóm cố định 'ServiceResultOfIFooData: ServiceResult ' các lớp và thay đổi OperationContracts để trả về các loại đó. Điều này làm cho tôi bị bệnh mặc dù vì nó vi phạm mục đích của việc có generics ở nơi đầu tiên. –
JMD
Tôi đã thử [ghi đè tên của DataContract] (http://msdn.microsoft.com/en-us/library/ms731045 (v = vs.100) .aspx) cho ServiceResult bằng cách sử dụng '[DataContract (Name =" ServiceResultOf {0} ")]' nhưng {0} vẫn được giải quyết thành "anyType", khi nhìn lại, là đáng thất vọng nhưng không hoàn toàn bất ngờ, vì đây có thể là chính xác những gì đang được thực hiện theo mặc định khi Name không bị ghi đè. –
JMD
Câu hỏi hay. Tôi đã có cùng một vấn đề và thực sự muốn tránh sử dụng các lớp cụ thể. Bạn có thể tìm thấy một giải pháp khác với giải pháp được đề cập trong câu trả lời được chấp nhận không? – smoksnes