2010-02-17 7 views
10

WCF는 스트리밍 된 MTOM 요청을 처리 할 때 Content-ID URI 참조에 http://tempuri/1/number을 사용합니다.WCF : (MTOM) xop에서 사용 된 구성표를 변경할 수있는 방법이 있습니까? WCF에서 생성 한 내용 참조 uris?

WCF가 xop에 대해 다른 Content-ID 참조를 사용하도록하는 방법이 있습니까? 다음을 포함합니까? 문제의

배경 :

내가 큰 데이터 업로드를 스트리밍 핸들 MTOM을 사용 잭스 WS 자바 웹 서비스를위한 .NET 클라이언트를 구축하고있다. 손으로 서비스 및 데이터 연락처를 만들었습니다 (WSDL 생성 계약은 정확하지 않았으며 스트리밍을 허용하지 않았습니다).

웹 서비스 (jax ws)가 데이터를 포함하는 요청 본문을받지 못하는 것이 문제입니다.

헤더로 전송 된 데이터를 수신합니다.

우리는 ws 용 자바 클라이언트를 만들었습니다. 이것은 작동합니다.

내가 캡처 자바와 WCF 요청을 발행 할 때 HTTP 트래픽을 비교하고, 유일한 차이점은 다중 데이터를 게시 할 때의 Content-ID 참조가 생성되는 방식에있다 :

  • WCF는 http://tempuri/1/... 콘텐츠 사용 href="cid:http%3A%2F%2Ftempuri.org%2F1%2F634019957020047928"

  • 자바 클라이언트와 같은 인코딩 값을 산출 -ID 참조, href="cid:[email protected]"

,536,913처럼, "이메일 스타일"URI를 사용 에서 63,210

이러한 수율 상기 멀티 데이터, 콘텐츠가 인코딩되지 의해 참조되며, 이후에 (데이터는 SOAP 바디에서 유일한 요소) (XOP includes specification)


//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:[email protected]"/> 
</Data> 

XOP가-포함 다음 콘텐츠 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 

나는이 잭스 웹 서비스 프레임 워크의 버그 일 수 있으며이 + WCF 생성 urlencode되고 콘텐츠 ID URI 참조를 인식하지 않는 것 같아요.

WCF가 xop에 대해 다른 Content-ID 참조를 사용하도록하는 방법이 있습니까? 다음을 포함합니까?


편집 : 나는 GenerateUriForMimePart 방법이있는 XmlMtomWriter을 발견, 이것은 콘텐츠 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

답변

1

긴 조사 후 자신에게 Asnwering : -에 관련된 거의 모든 것이 가능하지 않음을 전체 XmlMtomWriter 및 기타 관련 레이어와 WCF의 우려를 재 구현하지 않고

유사한 문제가 제공 대답은 도움이되지 않습니다, 여기에 설명되어 mtom 구현은 내부적입니다.

0

두 XOP에는 사용자가 표시 한 샘플이 W3C에 따라 정확하고 수용 가능합니다. URL 형식과 전자 메일 형식으로 각각 참조합니다.

저는 자바 개발자가 아니지만 특정 JAVA 웹 서비스와 인터페이스 할 때 유사한 문제를 상기합니다. 특정 JAVA 릴리스에 버그가 있음을 기억하고 있으며 (Java 개발자) 다음 릴리스 버전으로 업그레이드 한 후에이 문제는 사라졌습니다. 더 자세한 정보를 제공해 주셨으면 좋았을 때였지만 그 당시에는 와이어의 끝 부분에서 해결해야 할 문제가 충분히 있었고 결함 로그에 항목이 하나 더 적기 때문에 기뻤습니다.

//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:[email protected]"/> 
</Data> 
1

나는 그것이 오래된 질문이라는 것을 알고있다. 하지만 나는 이틀 전에 같은 문제에 직면 해있다.

내가 작동하는 방법을 찾았지만 매우 더러운 해킹입니다. (나는 그것을 알고 있습니다. 여기에 게시하지 않는 것이 좋지만 아마도 도움이 될 것입니다.) 희망을 갖고 나를 비난하지 않기를 바랍니다.

ContentId는 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); 
    } 
} 

나는 "InvariantCulture"를 WCF 호출 전에 만 사용할 수 있습니다.

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

CultureInfo.InvariantCulture는 전역 상태 개체입니다. 내 자신의 InvariantCulture를 활성화하면 다른 모든 스레드에 영향을줍니다. 다시 말하지만, 더러운 해킹입니다. 그러나 그것은 효과적이다.

+0

네, 이건 더럽지 만 작동하는 해결책을 찾는 것을 축하드립니다. 리플렉션을 통해 InvariantCulture를 대체 할 생각은 없었지만 실제로는 유일한 옵션 인 것 같습니다. – Marek