Generische Rückgabetypen mit Schnittstellentypparametern in WCF

Wie kann ich Interfacetypen in generischen Typparametern aus dem zurückgeben?OperationContracts in meinem WCF REST Service? Genauer gesagt funktioniert es für einen Vorgang, aber nicht, wenn ich einen zweiten Vorgang mit einem generischen hinzufügeT das ist eine Schnittstelle.

Ich verwende JSON als Anforderungs- und Antwortformat und füttere einen Nicht-WCF-Client, der die JSON-Antworten auf die benötigten Daten analysiert. Ich verwende weder SOAP noch die vom Dienst generierte WSDL.

Meine Serviceschnittstelle:

[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();
}

Ich ging wegGetCount() undGetDescription() In diesem Beispiel wird darauf hingewiesen, dass diese beiden generischen Ergebnisse gut funktionieren, es sich jedoch offensichtlich um konkrete Typen handelt. Und selbstGetFooData() funktioniert gut, bis ich eine zweite Methode hinzufügenIServiceResult<T> woherT ist eine Schnittstelle.

Die Rückgabetypen vonGetFooData() undGetBarData() sind nicht gleich, noch sind die konkreten Klassen, die sie implementieren.

Sie können sich vorstellen, dass ich die Implementierung auf ein Gerüst reduziert habe, da ich nicht denke, dass die Implementierung das Herzstück des Problems ist:

#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

Und die Fehlermeldung beim AufrufenGetBarData() vom Browser aus:

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. 

Der Rest der Fehlermeldung ist ein roter Hering über kollidierende SammlungsartenList<Test> undTest[], was hier nicht der Fall ist.

Deutlich,IFooData undIBarData sind weder gleich noch die Klassen, die sie implementieren.

Warum also?ServiceResult<IFooData> undServiceResult<IBarData> beide lösen sich aufServiceResultOfanyType?

Vermisse ich etwas oder gibt es keine Möglichkeit, dies zu beheben?

Antworten auf die Frage(1)

Ihre Antwort auf die Frage