2009-09-03 41 views
8

は、私は、次のしている:私は、GETメソッドを実行するとWCF:インタフェース、ジェネリックとServiceKnownType

[ServiceContract] 
[ServiceKnownType(typeof(ActionParameters))] 
[ServiceKnownType(typeof(SportProgram))] 
[ServiceKnownType(typeof(ActionResult<SportProgram>))] 
public interface ISportProgramBl 
{ 
    [OperationContract] 
    IActionResult<ISportProgram> Get(IActionParameters parameters); 
} 

を私は次のエラーを取得する:

There was an error while trying to serialize parameter http://tempuri.org/:GetResult . The InnerException message was 'Type 'PPS.Core.DomainModel.Support.Action.ActionResult`1[ [PPS.Core.DomainModel.SportProgram.ISportProgram, PPS.Core.DomainModel, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]' with data contract name 'ActionResultOfanyType: http://schemas.datacontract.org/2004/07/PPS.Core.DomainModel.Support.Action ' is not expected. Add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to DataContractSerializer.'. Please see InnerException for more details.

このエラーから私はそれができていることがわかります私がServiceKnownType(typeof(ActionResult <スポーツプログラム>))を持っていても、ActionResultを解決できません。

注これは、このようなルックスを発生させるリファレンススタブであるので、私は知らタイプが正しく越えて持ち込まれていることがわかります。

[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")] 
[System.ServiceModel.ServiceContractAttribute(ConfigurationName="SportProgramStb.ISportProgramBl")] 
public interface ISportProgramBl { 

    [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/ISportProgramBl/Get", ReplyAction="http://tempuri.org/ISportProgramBl/GetResponse")] 
    [System.ServiceModel.ServiceKnownTypeAttribute(typeof(PPS.Core.DomainModel.SportProgram.SportProgram))] 
    [System.ServiceModel.ServiceKnownTypeAttribute(typeof(PPS.Core.DomainModel.Support.Action.ActionParameters))] 
    [System.ServiceModel.ServiceKnownTypeAttribute(typeof(PPS.Core.DomainModel.Support.Action.ActionResult<PPS.Core.DomainModel.SportProgram.SportProgram>))] 
    object Get(object parameters); 
} 

は、なぜこれが間違って起こっている???? WCFサービスを正しく処理していることに注意してください...しかし、結果が返されると、例外をスローします。

最後のActionResultは次のようになります。

public interface IActionResult<T> 
{ 
    T Result { get; set; } 
} 

乾杯 アンソニー

+0

'Serializer'が期待する' ActionResult '型は' ServiceKnownType'で提供された 'ActionResult '型とは異なります! – Lightman

答えて

15

これは、SOA対OOPの「インピーダンスのミスマッチ」の別のケースだと思います。 2つの世界は全く別物です。

WCFでは、クライアントからサーバーに渡されるすべてがというシリアル化メッセージとして渡されます。参照は使用されていません。

これは、クライアント上でシリアル化し、サーバーに送信してそれを逆シリアル化して使用するためのものです。具体的な - あなたはインターフェースを渡すことはできません。 "ジェネリックス - あなたはそれを綴る必要があります。基本的に、クライアントからワイヤー経由でサーバーに渡されるのは、XMLスキーマで表現可能でなければなりません。

これは意味合いがたくさんあります。

  • なしのインターフェイスを - あなたは、インターフェイスを周りに渡すことはできません - あなただけの基底クラスとパスを定義することはできません - あなたは
  • なし「自動」の継承具象型で作業する必要がありますそれに基づいて、周りの派生クラス - これらの自動的なジェネリック医薬品
  • (つまりServiceKnownType属性が何のためにあるのかだ)あまりにもspecificiedする必要はない - もう一度、あなたの代わりに
具体的なタイプを使用する必要があります

これは多くの制限のように聞こえるかもしれませんが、WCFはすべてのメッセージベースの通信を使用しているため、レフェレンス、継承、ジェネリックなどは処理できません。

私は実際にあなた自身のための答えを持っていません - 私はちょうどあなたの戦略を再考し、あなたのクライアントとサーバーがWCFを介して情報を交換する方法を変更する必要があると思います。

マルク・

PS:私はいくつかのより多くの研究を行なったし、すべての私の理解に反し、限り、ワイヤー間のインターフェースおよび/または抽象基本クラスに基づいているものをシリアル化する方法があるように思われますあなたはそれが常にワイヤのどちらかの端にある.NET(つまりではなく、はJavaと相互運用可能であることがわかります)。

Aaron Skonnard blog post on the NetDataContractSerializer参照し、別のblog postyet anotherはあなたのメソッドにパラメータとしてIPersonのようなものを周りに渡すことができるようにNetDataContractSerializerを使用する方法を示します。

+0

WCFに必要なすべてのヒントを提供したいと思いますが、インターフェースやジェネリックの使用を避けることはできません。何とかインターフェースを取り除くことができれば、まだジェネリックを使用できますか?私はまだジェネリックスを取り除くことができる場合は逆の真実ですが、私はまだインターフェイスを使用することができます...意味は、それは私の問題を引き起こしている2の組み合わせです?ジェネリックを使用する必要のないより具体的なバージョンのIActionResult を作成することができました... –

+0

この問題の調査中に私が見つけたいくつかの新しい情報で私の投稿を更新しました。 –

+0

更新をありがとう...私のケースではNetDataContractSerializerはうまくいく... –

0

あなたは、コンクリートの型のオブジェクトのインターフェイスを指定していませんか?

編集:あなたはジェネリックに渡しているすべての具体的な種類があり

は私が言っているものですが(インタフェースを介してサブオブジェクトを含む)既知の型のリストに渡されます。私たちはすべてのタイプが知られていないシリアス化問題を持っていました。

+0

あなたが何を意味しますかそれ?コンフリクトオブジェクトはインターフェイスを実装しています... – vdhant

0

あなたはTのIListを返しています。おそらく、Tが何であるかを知るのに問題があるかもしれません。

タイプではなくインターフェイスを返すのがよいかどうかはわかりません。

2

これは、ServiceStack.NET - My Open Source .NETとMONO Web Services Frameworkで解決する問題の1つです。

サービススタックには、Martin Fowlers Data Transfer Object Patternの影響を大きく受けました.DTOを使用して簡単にWebサービス(つまりSOAの方法)を定義することができます。

私はWCFに固有のWSDLを生成することで、このような制限を回避しています。 WCFの複雑な構成/ ServiceContractのモデルを置き換えるメリットとして、SOAP WebサービスはMONO-see the live demoでも動作します。

+0

興味深いですが、ライブデモのリンクは404です –

1

これは古い質問であり、受け入れられた回答はまったく正しいものですが、私は類似の問題を探してこれを突き詰めて、自分の経験を共有できると考えました。これはしばしば頭痛ですが、WCFとのインターフェースを組み合わせたジェネリックを使用することは可能です。ここで私がやった別の(似)の実装の作業例を示します。ここ

[ServiceContract] 
[ServiceKnownType(typeof(CollectionWrapper<IAssociation>))] 
public interface IService : 
{ 
    [OperationContract] 
    ICollectionWrapper<IAssociation> FindAssociation(string name, int pageSize, int page); 
} 

public interface ICollectionWrapper<TModel> 
{ 
    int TotalCount { get; set; } 
    IEnumerable<TModel> Items { get; set; } 
} 

[KnownType(typeof(OrganizationDto))] 
[KnownType(typeof(CompanyDto))] 
public class CollectionWrapper<TModel> : ICollectionWrapper<TModel> 
{ 
    [DataMember] 
    public int TotalCount { get; set; } 
    [DataMember] 
    public IEnumerable<TModel> Items { get; set; } 
} 

public class CompanyDto : IAssociation 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
} 

public class OrganizationDto : IAssociation 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
} 

キーはKnownTypeServiceKnownTypeの組み合わせを使用することです。

は、だからあなたの場合には、あなたがこのような何かを行うことができます。

[ServiceContract] 
[ServiceKnownType(typeof(ActionParameters))] 
[ServiceKnownType(typeof(ActionResult<ISportProgram>))] // Actual implementation of container, but interface of generic. 
public interface ISportProgramBl 
{ 
    [OperationContract] 
    IActionResult<ISportProgram> Get(IActionParameters parameters); 
} 

[KnownType(typeof(SportProgram))] // Actual implementation here. 
public class ActionResult<T> 
{ 
    // Other stuff here 
    T FooModel { get; set; } 
} 

これは、あなたが共有契約(実際のサービス・インターフェースへのアクセス)を持っている場合は動作し、ChannelFactory<ISportProgramBl>との契約を消費します。私はそれがサービス参照で動作するかどうかわかりません。

しかし、ここで述べたように実装していくつかの問題があるようです:

WCF With a interface and a generic model

、別の似質問はここで尋ねたと答えた:

Generic return types with interface type params in WCF

関連する問題