내 WCF REST 서비스의 OperationContracts
에서 일반 형식 매개 변수의 인터페이스 형식을 반환하려면 어떻게해야합니까? 더 구체적으로 말하자면, 하나의 연산에서 작동하지만, 인터페이스 인 일반 T
을 가진 두 번째 연산을 추가 할 때가 아닙니다.WCF의 인터페이스 유형 매개 변수를 사용하는 일반 반환 형식
요청 및 응답 형식으로 JSON 응답에 필요한 데이터를 구문 분석하는 비 WCF 클라이언트에게 제공되는 JSON을 사용하고 있습니다. SOAP 또는 서비스에서 생성 된 WSDL을 사용하지 않습니다.
내 서비스 인터페이스 :
[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();
}
나는 그 두 가지 일반적인 결과가 잘 작동 지적 예에서 GetCount()
및 GetDescription()
을 왼쪽하지만 분명히 그들은 콘크리트 종류가 있습니다. 그리고 이 인터페이스 인 IServiceResult<T>
의 두 번째 방법을 추가 할 때까지 GetFooData()
도 문제없이 작동합니다.
반환 유형은 GetFooData()
과 GetBarData()
이 같지 않으며이를 구현하는 구체적인 클래스도 아닙니다.
당신은 내가 구현이 문제의 핵심이다 생각하지 않는 한 나는 골격 구현을 감소했습니다 상상할 수 : 나는 브라우저에서 GetBarData()
를 호출 할 때
#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
그리고 오류 메시지 : 오류 메시지의
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.
나머지는 여기에 사실이 아니다 충돌 수집 유형 List<Test>
및 Test[]
에 대한 레드 헤링 (Red Herring)이다.
분명히 IFooData
과 IBarData
은 동일하지 않으며 해당 클래스를 구현하는 클래스도 아닙니다.
그렇다면 ServiceResult<IFooData>
과 ServiceResult<IBarData>
은 모두 ServiceResultOfanyType
으로 해결됩니까?
내가 누락되었거나 해결할 방법이 없습니까?
지금까지 살펴본 유일한 해결책은 Generic ServiceResult 유형을 고정 된 'ServiceResultOfIFooData : ServiceResult'클래스로 평평하게하고 해당 유형을 대신 반환하도록 OperationContracts를 변경하는 것입니다. 이것은 처음부터 generics를 가지고있는 목적을 위반하기 때문에 나를 아프게합니다. –
JMD
ServiceResult에 대해 [DataContract (Name = ")를 사용하여 [DataContract의 이름 재정의] (http://msdn.microsoft.com/en-us/library/ms731045(v=vs.100).aspx) 되돌아 보면 실망 스럽지만 완전히 예기치 않은 "anyType"으로 {0}이 여전히 해결됩니다. Name이 대체되지 않은 경우 기본적으로 수행되는 작업 일 것입니다. –
JMD
큰 질문입니다. 나는 동일한 문제를 안고 있으며 실제로 구체적인 클래스를 사용하지 않으려합니다. 수락 된 답변에서 언급 한 해결책 이외의 다른 해결책을 찾았습니까? – smoksnes