1

クライアントから WCF サービスへのオブジェクトの転送に問題があります。標準のコントラクト定義は、複数の異なるアプリの汎用サービスであるため、使用できません。

サーバーとクライアントは両方とも、転送される型が定義されているアセンブリを持っているため、サーバーは SOAP メッセージからオブジェクト インスタンスを逆シリアル化できます。最初に、このオブジェクトを「そのまま」送信し​​ようとしましたが、予期しないコントラクト名に関するメッセージが表示されました。たとえば、KnownTypeAttribute 属性を使用するか、DataContractSerializer に渡される既知の型のリストにそれらを追加することによって、既知の型のリストに静的に追加します。

調査の結果、この問題を解決するにはいくつかの方法があることがわかりました。 3. DataContractResolver を使用します (アセンブリを調べてそれらの型を見つけようとするので問題ありません)

この記事を学習した後 - http://code.msdn.microsoft.com/windowsdesktop/WCF-Data-Contract-Resolver-7de9b8b4#content - プロジェクトでリゾルバーを置き換える属性を作成しました (IIS でホストされているため) ):

public class DataContractResolverAttribute: Attribute, IOperationBehavior
{
    private Type _resolverType = null;

    public DataContractResolverAttribute (Type resolver)
    {
        _resolverType = resolver;
    }

    public void AddBindingParameters (OperationDescription description, BindingParameterCollection parameters)
    {
    }

    public void ApplyClientBehavior (OperationDescription description, ClientOperation proxy)
    {
        AddResolverToOperation(description);
    }

    public void ApplyDispatchBehavior (OperationDescription description, DispatchOperation dispatch)
    {
        AddResolverToOperation(description);
    }

    public void Validate (OperationDescription description)
    {
    }

    private void AddResolverToOperation (OperationDescription description)
    {
        DataContractSerializerOperationBehavior dcs = description.Behaviors.Find<DataContractSerializerOperationBehavior>();
        if (dcs != null)
        {
            dcs.DataContractResolver = Activator.CreateInstance(_resolverType) as DataContractResolver;
        }
    }
}

また、この属性を操作に割り当てました。

    [OperationContract]
    [FaultContract(typeof(string))]
    [DataContractResolver(typeof(CustomResolver))]
    RuleResultData ExecuteRuleObj (object context, int ruleId);

CustomResolver は DataContractResolver の子孫です。

class CustomResolver: DataContractResolver
{
    public override Type ResolveName (string typeName, string typeNamespace, Type declaredType, DataContractResolver knownTypeResolver)
    {
        // ... not significant here ...
    }

    public override bool TryResolveType (Type type, Type declaredType, DataContractResolver knownTypeResolver, out XmlDictionaryString typeName, out XmlDictionaryString typeNamespace)
    {
        // ... not significant here ...
    } 
}

デバッグ時に、リゾルバーが正常に置換されていることがわかります ( AddResolverToOperation にブレークポイントを設定します) が、呼び出し時に何の効果も見られません ( ResolveName および TryResolveType のブレークポイントはトリガーされません)。

そんな迷惑なリゾルバの振る舞いについて、手掛かりを教えてください。

前もって感謝します。アレクセイ・ヴィシニャコフ、ロシア。

4

0 に答える 0