2013-04-23 5 views
2

WCF를 사용하여 외부 (즉, 계약을 제어 할 수 없음) REST 서비스를 호출하려고한다고 상상해보십시오. 나는이WCF UriTemplate UrlEncode

[ServiceContract] 
public interface ISomeRestApi 
{ 
    [OperationContract] 
    [WebInvoke(Method = "PUT", UriTemplate = "blablabla/{parameter1}/{parameter2}")] 
    void PutSomething(string parameter1, string parameter2); 
} 

내 매개 변수 중 하나는 슬래시 (/) 내 UriTemplate 경로 매개 변수를 urlencode WCF를 강제로 어떻게

public class Test{ 

    [Fact] 
    public void TestPutSomething() 
    { 
     ISomeRestApi api = CreateApi(); 

     //this results in the url: http://server/blablabla///someotherparam 
     api.PutSomething("/", "someotherparam"); 

     //this also results in the url: http://server/blablabla///someotherparam 
     api.PutSomething(HttpUtility.UrlEncode("/"), "someotherparam"); 

     //but i want: http://server/blablabla/%2F/someotherparam 
    } 
} 

이라고 말할 다음 계약?

+0

[가능한 슬래시 및 다른 'URL 민감한'문자를 WCF REST 서비스에 전달할 수 있습니까?] (http://stackoverflow.com/questions/7176726/how-can-i-pass-slash-and) -other-url-sensitive-characters-to-a-wcf-rest-service) –

+0

호출 된 외부 서비스를 제어 할 수 없어 링크 된 질문의 대답은이 질문에 대한 유효한 대답이 아닙니다. 서비스 계약에있는 uritemplate은 불가능합니다. 이 제약 조건을 반영하도록 질문을 수정했습니다. – Stif

답변

0

많은 시행 착오를 통해 나는 내 문제에 대해 매우 추악하고 완전히 비논리적 인 해결책을 발견했습니다. 하지만 여전히 ...이 게시물은 앞으로 누군가를 도울 수 있습니다. 이 "솔루션"은 .NET 4.5에서 유용합니다. 나는 그것이 당신을 위해 일할 것이라는 것을 보장하지 않습니다.

문제는이 내려 온다 :

다음 포스트는 "오른쪽"방향으로 날을 넣어 그래서

/// <summary> 
/// Client enpoint behavior that enables the use of a escaped forward slash between 2 forward slashes in a url 
/// </summary> 
public class EncodeForwardSlashBehavior:IEndpointBehavior 
{ 
    public void Validate(ServiceEndpoint endpoint) 
    { 

    } 

    public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters) 
    { 

    } 

    public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher) 
    { 

    } 

    public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime) 
    { 
     clientRuntime.ClientMessageInspectors.Add(new ForwardSlashUrlInspector()); 
    } 
} 

/// <summary> 
/// Inspector that modifies a an Url replacing /// with /%2f/ 
/// </summary> 
public class ForwardSlashUrlInspector:IClientMessageInspector 
{ 
    public object BeforeSendRequest(ref Message request, IClientChannel channel) 
    { 
     string uriString = request.Headers.To.ToString().Replace("///", "/%2f/"); 
     request.Headers.To = new Uri(uriString); 
     AddAllowAnyOtherHostFlagToHttpUriParser(); 

     return null; 
    } 

    /// <summary> 
    /// This is one of the weirdest hacks I ever had to do, so no guarantees can be given to this working all possible scenarios 
    /// What this does is, it adds the AllowAnyOtherHost flag to the private field m_Flag on the UriParser for the http scheme. 
    /// Replacing /// with /%2f/ in the request.Headers.To uri BEFORE calling this method will make sure %2f remains unescaped in your Uri 
    /// Why does this work, I don't know! 
    /// </summary> 
    private void AddAllowAnyOtherHostFlagToHttpUriParser() 
    { 
     var getSyntaxMethod = 
      typeof(UriParser).GetMethod("GetSyntax", BindingFlags.Static | BindingFlags.NonPublic); 
     if (getSyntaxMethod == null) 
     { 
      throw new MissingMethodException("UriParser", "GetSyntax"); 
     } 
     var uriParser = getSyntaxMethod.Invoke(null, new object[] { "http" }); 

     var flagsField = 
      uriParser.GetType().BaseType.GetField("m_Flags", BindingFlags.Instance|BindingFlags.NonPublic); 
     if (flagsField == null) 
     { 
      throw new MissingFieldException("UriParser", "m_Flags"); 
     } 
     int oldValue = (int)flagsField.GetValue(uriParser); 
     oldValue += 4096; 
     flagsField.SetValue(uriParser, oldValue); 
    } 


    public void AfterReceiveReply(ref Message reply, object correlationState) 
    { 

    } 
} 

: 등 난 다음 코드 조각 해낸 리버스 엔지니어링하고, 인터넷 검색, 저주의 많은 후

그리고 아무 소용로 포스트에서 제안 솔루션,하지만 ...을 시도 기본적으로 UriParser 내부의 전용 변수에 열거 플래그를 추가하는 리플렉션을 사용하는 사용자 지정 EndpointBehavior를 만듭니다. 이건 내 요청에 따른 도망 치는 슬래시를 막는 것 같습니다. 헤더. 언니가 이스케이프되지 않도록.

+0

문자를 이스케이프 처리 할 수 ​​있습니다. 링크 된 답변을 참조하십시오. –