2009-05-05 20 views
4

先ほどの質問serialising an object to an XmlDocument in C#については、asmxスタイルのWebサービス呼び出しから返されたXmlDocumentにいくつかのフォルト情報をシリアル化する必要がありました。クライアント上で私はXmlDocumentをオブジェクトに逆シリアル化する必要があります。XMLにシリアライズしてシリアライズされたオブジェクトの型を含める

タイプを知っていれば分かりやすいですが、デシリアライズするタイプもXmlDocumentでエンコードされている柔軟なアプローチが必要なことがわかりました。私が最初にXmlDocumentから戻って、このタイプ名を取得し、タイプを作成

Type type = fault.GetType(); 
    string assemblyName = type.Assembly.FullName; 

    // Strip off the version and culture info 
    assemblyName = assemblyName.Substring(0, assemblyName.IndexOf(",")).Trim(); 

    string typeName = type.FullName + ", " + assemblyName; 

を次にクライアント上:私は現在、次のように計算され、タイプ名を持つXmlDocumentXmlNodeを追加することによって、手動でやっていますこれXmlSerialiserに渡されるオブジェクト:

 object fault; 
     XmlNode faultNode = e.Detail.FirstChild; 
     XmlNode faultTypeNode = faultNode.NextSibling; 

     // The typename of the fault type is the inner xml of the first node 
     string typeName = faultTypeNode.InnerXml; 
     Type faultType = Type.GetType(typeName); 

     // The serialised data for the fault is the second node 
     using (var stream = new StringReader(faultNode.OuterXml)) 
     { 
      var serialiser = new XmlSerializer(faultType); 
      objectThatWasSerialised = serialiser.Deserialize(stream); 
     } 

     return (CastToType)fault; 

は、これは強引なアプローチである、と私は何とか、自動的にシリアル化されたタイプの型名を含む、よりエレガントな解決策があるかどう不思議ではなく、手動で記録しました。それ以外の場所?

答えて

3

私は同様の問題に直面していましたが、私は同じ解決策を思いつきました。限り、私は懸念している、それはXMLのシリアル化の値と型を一緒に保つための唯一の方法です。

私も同じようにアセンブリのバージョンをカットしています。しかし、私は彼らの署名がそのように見えるとして、あなたがジェネリック型とのトラブルを持っていることを、言及したいと思います:

System.Nullable`1[[System.Int, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 

だから私はあると思われ、唯一のアセンブリバージョン(複数可)をカットする機能を作りましたバージョン管理の問題を解消するのに十分です。

private static string CutOutVersionNumbers(string fullTypeName) 
    { 
     string shortTypeName = fullTypeName; 
     var versionIndex = shortTypeName.IndexOf("Version"); 
     while (versionIndex != -1) 
     { 
      int commaIndex = shortTypeName.IndexOf(",", versionIndex); 
      shortTypeName = shortTypeName.Remove(versionIndex, commaIndex - versionIndex + 1); 
      versionIndex = shortTypeName.IndexOf("Version"); 
     } 
     return shortTypeName; 
    } 
+0

+1は良いコピー/ペースト可能なコードを提供し、私の人生をちょっと簡単にします。 – Phil

0

ニール、なぜクライアントとサーバーの両方で同じタイプになる必要がありますか?

まだクライアントでASMXを使用していますか?それは、ASMXが障害を適切にサポートしていないため、理由があります。

また、単純なスイッチステートメントで使用する正しいタイプを判別できないほど多くの異なるフォルトタイプがありますか。

+0

私はサーバーとクライアントでasmxを使用しています。私はasmxサービスへのインターフェースを使用しているので、そのインターフェースのユーザーがSoapExceptionsを取得しないようにするため、ハーフベイクドWCFのような欠陥システムを実装しています代わりにFaultプロパティを持つServiceExceptionを呼び出しました。そのfaultプロパティは、SoapException.Detailプロパティ、つまりXmlDocument/XmlNodeのシリアル化でasmxクライアントに返されます。現時点では多くのフォルトタイプはありませんが、私は、展開されたクライアントを壊さずにサーバーにもっと多くの機能を追加できるようにしたいと考えています。 –

+1

だから、あなたは車輪を再発明していません。あなたはWCFを改革しています。 –

関連する問題