2011-08-18 3 views
12

.NET 프레임 워크에서 버그를 발견 했습니까? 아니면 잘못 했나요?암호는 WCF에 영국 파운드를 포함 할 수 없습니까?

다음은 이야기입니다.

나는 그 같은 WCF 채널에 암호 어제 설정하려고했다 :

System.ServiceModel.CommunicationException 
    Message=An error (The request was aborted: The request was canceled.) occurred while transmitting data over the HTTP channel. 
    Source=mscorlib 
    StackTrace: 
    Server stack trace: 
     at System.ServiceModel.Channels.HttpChannelUtilities.ProcessGetResponseWebException(WebException webException, HttpWebRequest request, HttpAbortReason abortReason) 
     at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout) 
     at System.ServiceModel.Channels.RequestChannel.Request(Message message, TimeSpan timeout) 
     at System.ServiceModel.Dispatcher.RequestChannelBinder.Request(Message message, TimeSpan timeout) 
     at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout) 
     at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs) 
     at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation) 
     at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message) 
    Exception rethrown at [0]: 
     at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg) 
     at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type) 
     at PocketKings.Tools.Services.PopulationManager.Client.PopulationService.IPopulationService.ResolvePopulationMember(ResolveRealmMemberQuery request) 
    InnerException: System.Net.WebException 
     Message=The request was aborted: The request was canceled. 
     Source=System 
     StackTrace: 
      at System.Net.HttpWebRequest.GetResponse() 
      at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout) 
     InnerException: System.NotSupportedException 
      Message=This method is not supported by this class. 
      Source=System 
      StackTrace: 
        at System.Net.BasicClient.EncodingRightGetBytes(String rawString) 
        at System.Net.BasicClient.Lookup(HttpWebRequest httpWebRequest, ICredentials credentials) 
        at System.Net.BasicClient.Authenticate(String challenge, WebRequest webRequest, ICredentials credentials) 
        at System.Net.AuthenticationManager.Authenticate(String challenge, WebRequest request, ICredentials credentials) 
        at System.Net.AuthenticationState.AttemptAuthenticate(HttpWebRequest httpWebRequest, ICredentials authInfo) 
        at System.Net.HttpWebRequest.CheckResubmitForAuth() 
        at System.Net.HttpWebRequest.CheckResubmit(Exception& e) 
        at System.Net.HttpWebRequest.DoSubmitRequestProcessing(Exception& exception) 
        at System.Net.HttpWebRequest.ProcessResponse() 
        at System.Net.HttpWebRequest.SetResponse(CoreResponseData coreResponseData) 

그래서 내가보기 시작 :이 오류를 받았을 때 웹 서비스 메서드를 호출 한 후

channelFactory.Credentials.UserName.UserName = credentials.Username; 
channelFactory.Credentials.UserName.Password = credentials.Password; 

및 그것과 기록에 나는 심지어 서버까지 가지 않는다는 것을 보여준다. 예외를 throw하는 .NET Framework 메서드 (System.Net.BasicClient.EncodingRightGetBytes (string rawString))는 영국 파운드 기호 (£)를 좋아하지 않습니다.

나는 반사경의 방법을 복사하고 빠른 단위 테스트를 쓰고 파운드 모두에서 나는 키보드에 입력 할 수 있습니다 것처럼 나던있는 유일한 문자입니다 :이 확인 내 단위 테스트가

internal static byte[] EncodingRightGetBytes(string rawString) 
    { 
      byte[] bytes = Encoding.Default.GetBytes(rawString); 
      string strB = Encoding.Default.GetString(bytes); 

      if (string.Compare(rawString, strB, StringComparison.Ordinal) != 0) 
     { 
      throw ExceptionHelper.MethodNotSupportedException; 
     } 
     return bytes; 
} 

입니다 이 방법

[Test] 
public void test123() 
{ 
     string domain = "localhost"; 
     string userName = "lukk"; 

     string charactersToCheck = @"¬`!£$%^&*()_+={}[]:;@'~#<>,.?/|\"; 

     foreach (var character in charactersToCheck.ToCharArray()) 
     { 
       string internalGetPassword = character.ToString(); 

       try 
       { 
        // begin - this assignement was copied from System.Net.BasicClient.Lookup method 
        byte[] inArray = EncodingRightGetBytes(
          (!string.IsNullOrEmpty(domain) ? (domain + @"\") : "") 
          + userName 
          + ":" 
          + internalGetPassword); 
        //end 
       } 
       catch (Exception ex) 
       { 
        Console.WriteLine(string.Format("this character is bad: {0}", internalGetPassword)); 
       } 
     } 
} 

당신이 EncodingRightGetBytes을 볼 수 있듯이 두 문자열을 비교 원래 문자열 (rawString는) 영국 파운드가 포함되어있는 경우 그들은 다르다. 나는 교체 할 때

EncodingRightGetBytes 잘 작동과 함께 ...

그들 중 하나이되고,이 방법의 이름은 거의 링크를 찾아온다 인터넷 검색을 "Encoding.Default을." "Encoding.UTF8." http://support.microsoft.com/kb/943511

asp.net 프로젝트에서 .net 3.5를 사용하도록 설정된 VS 2010을 사용하고 있습니다.

.NET Framework의 버그일까요? 아니면 잘못된 것입니까?

편집 : 내 테스트를 실행하는 동안 내가 직접 실행 창에 Encoding.Default를 조회 할 때 나는이 얻을 :

내가 ASP와 비슷한 경험
?Encoding.Default 
    {System.Text.SBCSCodePageEncoding} 
    [System.Text.SBCSCodePageEncoding]: {System.Text.SBCSCodePageEncoding} 
    BodyName: "iso-8859-2" 
    CodePage: 1250 
    dataItem: {System.Globalization.CodePageDataItem} 
    decoderFallback: {System.Text.InternalDecoderBestFitFallback} 
    DecoderFallback: {System.Text.InternalDecoderBestFitFallback} 
    EncoderFallback: {System.Text.InternalEncoderBestFitFallback} 
    encoderFallback: {System.Text.InternalEncoderBestFitFallback} 
    EncodingName: "Central European (Windows)" 
    HeaderName: "windows-1250" 
    IsBrowserDisplay: true 
    IsBrowserSave: true 
    IsMailNewsDisplay: true 
    IsMailNewsSave: true 
    IsReadOnly: true 
    IsSingleByte: true 
    m_codePage: 1250 
    m_deserializedFromEverett: false 
    m_isReadOnly: true 
    WebName: "windows-1250" 
    WindowsCodePage: 1250 
+1

영국 키보드를 사용한다고 가정하면 ±, § 또는 €을 문자열의 일부로 입력하면 어떻게됩니까? (모두 영국 키보드에서 찾을 수 있습니다)? 이것도 실패한다면, 문제는 분명히 7 대 8 비트 인코딩입니다.이 모든 문자는 128을 넘는 코드 (즉 8 비트 사용)를 가지므로 기본 인코딩으로 올바르게 처리 할 수 ​​없습니다. 라틴어 1 또는 그 변형입니다. 인코딩을 UTF8로 변경하는 방법이 있습니까? –

+0

파운드 문자가 '확장 된'ASCII 문자로 인코딩되는 것과 같이 소리가납니다. 사용 된 코드 페이지를 알고있는 경우에만 이해할 수 있습니다 (분명히 암호 해시에는 사용 된 코드 페이지가 포함되지 않습니다. 그것을 만든다), 그래서 인코딩 방법은 모호하게 인코딩 된 문자를 올바르게 거부 할 수있다. UTF8은 올바른 솔루션처럼 들립니다. – David

+0

안녕 얘들 아, 의견에 감사드립니다. @Aleks - 필자는 테스트 문자열에 "± § €"의 세 문자를 추가했으며 모두 테스트에 합격했습니다. BTW 내 키보드는 영어 (아일랜드) – lukk

답변

2

, 내가 관리 사용하여이 문제를 해결하기 위해 다음 구성. 당신이

<serviceHostingEnvironment aspNetCompatibilityEnabled="true"/> 

업데이트를 설정 세계화 태그가 WCF에 대해 동일하게 작동 내 지식

<system.web>  
<globalization 
fileEncoding="utf-8" 
requestEncoding="utf-8"  
responseEncoding="utf-8" 
culture="en-GB" 
uiCulture="en-GB"/> 
... 

는 :

The ASP.NET configuration language allows you to specify the culture for individual services. The WCF does not support that configuration setting except in ASP.NET compatibility mode. To localize a WCF service that does not use ASP.NET compatibility mode, compile the service type into culture-specific assemblies, and have separate culture-specific endpoints for each culture-specific assembly.

: 그냥 다음과 같은 내용의 페이지 하단에 MSDN을 확인
관련 문제