WCF:(MTOM) WCF によって生成された xop:Content 参照 URI で使用されるスキームを変更する方法はありますか?

StackOverflow https://stackoverflow.com/questions/2280025

  •  21-09-2019
  •  | 
  •  

質問

WCF は使用します http://tempuri/1/number ストリーミングされた MTOM リクエストを処理するときの Content-ID URI 参照用。

WCF で xop:Include に別の Content-ID 参照を使用するように強制する方法はありますか?

問題の背景:

ストリーミングされた大規模なデータのアップロードを処理する、MTOM 対応の jax ws Java Web サービス用の .NET クライアントを構築しています。サービスとデータのコンタクトを手動で作成しました (WSDL で生成されたコントラクトが正しくなく、ストリーミングが許可されませんでした)。

問題は、Web サービス (jax ws) がデータを含むリクエスト本文を受信しないことです。

ヘッダーで転送されたデータを受信します。

ws 用の Java クライアントを構築しました。これは機能します。

Java と wcf からリクエストを発行するときの HTTP トラフィックをキャプチャして比較しました。唯一の違いは、マルチパート データを投稿するときに Content-ID 参照が生成される方法です。

  • WCF は使用します http://tempuri/1/... エンコードされた値を生成する Content-ID 参照。 href="cid:http%3A%2F%2Ftempuri.org%2F1%2F634019957020047928"

  • Java クライアントは、次のような「電子メール形式」の URI を使用します。 href="cid:3f3ec388-8cd9-47aa-a603-fb1bc17935b8@example.jaxws.sun.com"

これらにより、次の xop-includes が生成されます (データは SOAP 本体内の唯一の要素です) (XOPには仕様が含まれています)


//WCF:
<Data>
   <xop:Include xmlns:xop="http://www.w3.org/2004/08/xop/include" href="cid:http%3A%2F%2Ftempuri.org%2F1%2F634019957020047928" />
</Data>

//JAVA:
<Data>
    <xop:Include xmlns:xop="http://www.w3.org/2004/08/xop/include" href="cid:3f3ec388-8cd9-47aa-a603-fb1bc17935b8@example.jaxws.sun.com"/>
</Data>

その後、マルチパート データ内で、コンテンツはエンコードされていない Content-ID によって参照されます。

--uuid:7e166bb7-042f-4ba3-b6ef-98fbbc21244b+id=1
Content-ID: <http://tempuri.org/1/634019957020047928>
Content-Transfer-Encoding: binary
Content-Type: application/octet-stream

そこだと思います 5月 これは JAX Web サービス フレームワークのバグであり、WCF で生成され URL コード化された Content-ID URI 参照を認識しません。

WCF で xop:Include に別の Content-ID 参照を使用するように強制する方法はありますか?


編集:GenerateUriForMimePart メソッドを持つ XmlMtomWriter を見つけました。これは Content-ID を生成するために使用されます。

public static string GenerateUriForMimePart(int index)
{
    return string.Format(CultureInfo.InvariantCulture, 
"http://tempuri.org/{0}/{1}", new object[] { index, DateTime.Now.Ticks });
}

ID の生成は決してオーバーライド可能ではないようです。

同様の問題がここで説明されていますが、提供された回答は役に立ちません。 http://social.msdn.microsoft.com/Forums/en/wcf/thread/f90affbd-f431-4602-a81d-cc66c049e351

役に立ちましたか?

解決

長い調査の後、自分自身にAsnwering:不可全体XmlMtomWriterおよびその他の関連する層とWCFでの懸念を再実装することなく、 - MTOMの実装に関わるほとんどすべてが内部である

他のヒント

私はそれが古い質問です知っています。しかし、私は2日前に同じ問題に直面しています。

私は動作しますが、それは非常に非常に汚いハックのある方法を発見した(私はそれを知っている。私はおよそここでそれを公開していないが、おそらくそれは誰かに役立つだろう。と思った)うまくいけば、あなたはそのために私を責めないであろう。

はコンテンツIDは、CultureInfo.InvariantCultureを使用してフォーマットされます。私は、カスタムのCultureInfoでそれを置き換えるための公式の方法を見つけることができませんでした。しかし、反射の助けを借りて、私はそれを実行しました。次の実装は、.NET 4.0のためだけです。

public class NoTempUriInvariantCultureInfo : CultureInfo, ICustomFormatter
{
   private static CultureInfo originalCulture;
   private static object originalCultureLock;
   private static int enableCounter;

   private NoTempUriInvariantCultureInfo(CultureInfo invariantCulture)
      : base(invariantCulture.Name)
   {
      originalCulture = invariantCulture;
   }

   public static void Enable()
   {
      if(originalCultureLock == null)
         originalCultureLock = new object();

      lock (originalCultureLock)
      {
         if (enableCounter == 0)
         {
            var mInvCultField = typeof (CultureInfo).GetField("s_InvariantCultureInfo", BindingFlags.NonPublic | BindingFlags.Static);
            mInvCultField.SetValue(null, new NoTempUriInvariantCultureInfo(CultureInfo.InvariantCulture));
         }
         enableCounter++;
      }
   }

   public static void Disable()
   {
      lock (originalCulture)
      {
         if (enableCounter == 0)
            return;

         enableCounter--;
         if (enableCounter == 0)
         {
            var mInvCultField = typeof (CultureInfo).GetField("s_InvariantCultureInfo", BindingFlags.NonPublic | BindingFlags.Static);
            mInvCultField.SetValue(null, NoTempUriInvariantCultureInfo.originalCulture);
         }
      }
   }

   public override object GetFormat(Type formatType)
   {
      var result = originalCulture.GetFormat(formatType);
      return result ?? this;
   }

   public string Format(string format, object arg, IFormatProvider formatProvider)
   {
      if (format == null)
         return System.Text.RegularExpressions.Regex.Replace(arg.ToString().Replace("http%3A%2F%2Ftempuri.org%2F1%2F", ""), "http[:][/][/]tempuri[.]org[/][0-9]+[/]*", "");
      return String.Format("{0:" + format + "}", arg);
   }
}

私はWCF呼び出しの前に自分の "にInvariantCultureを" 有効ます。

NoTempUriInvariantCultureInfo.Enable();
try
{
    // make your call
}
finally
{
    NoTempUriInvariantCultureInfo.Disable();
}

CultureInfo.InvariantCultureは、グローバル状態オブジェクトです。私自身にInvariantCultureを有効にすると、他のすべてのスレッドに影響を与えます。 ここでも、それは汚いハックです。しかし、それは動作します。

はXOPの両方を使用すると、W3Cによると正しいと許容可能であることが示されたサンプルを含みます。私は、それぞれのURL形式と電子メールの形式としてそれらを参照してください。

私は、Java開発者ではないですが、特定のJava Webサービスとのインタフェース時に似問題を思い出します。私は、バグが特定のJavaリリースにそこにいる思い出すと、彼ら(JAVAの開発者)は次のリリースバージョンにアップグレードした後、この問題は単に去っていきました。私は、私はあなたより多くの詳細を提供することがしたい、しかし、一度、そこにワイヤーの私の端からアドレスへの私のために十分な問題だったと私は欠陥ログの1つの以下のアイテムを持っているだけで嬉しかったです。

//WCF: using URL format
<Data>
   <xop:Include xmlns:xop="http://www.w3.org/2004/08/xop/include" href="cid:http%3A%2F%2Ftempuri.org%2F1%2F634019957020047928" />
</Data>

//JAVA: using EMAIL format
<Data>
    <xop:Include xmlns:xop="http://www.w3.org/2004/08/xop/include" href="cid:3f3ec388-8cd9-47aa-a603-fb1bc17935b8@example.jaxws.sun.com"/>
</Data>
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top