2011-08-18 28 views
12

Tôi đã phát hiện ra một lỗi trong khung công tác .NET hay tôi đang làm gì sai?mật khẩu không thể chứa bảng Anh trong WCF?

Đây là câu chuyện.

Tôi đã cố gắng để thiết lập một mật khẩu trên kênh WCF ngày hôm qua như thế:

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

và sau đó gọi phương thức dịch vụ web khi tôi đã nhận lỗi này:

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) 

Vì vậy, tôi bắt đầu tìm kiếm tại đó và các bản ghi cho thấy rằng tôi thậm chí không nhận được như xa như máy chủ. Nó chỉ ra rằng các.NET framework phương pháp, mà ném một ngoại lệ (System.Net.BasicClient.EncodingRightGetBytes (String rawString)) không giống như dấu hiệu người Anh pound (£).

tôi sao chép các phương pháp từ các phản xạ và đã viết một bài kiểm tra đơn vị nhanh chóng và đồng bảng Anh là nhân vật duy nhất mà nó không giống như từ khắp nơi tôi có thể gõ trên bàn phím:

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; 
} 

Đây là bài kiểm tra đơn vị của tôi để kiểm tra phương pháp này:

[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)); 
       } 
     } 
} 

Như bạn thấy EncodingRightGetBytes so sánh hai chuỗi và chúng khác nhau nếu chuỗi gốc (rawString) chứa bảng Anh.

EncodingRightGetBytes hoạt động tốt khi tôi thay thế với ...

Googling tên phương pháp này mang lại rất ít liên kết, một trong số họ là này “Encoding.Default.” “Encoding.UTF8.”: http://support.microsoft.com/kb/943511

Tôi đang sử dụng VS 2010 với một dự án asp.net được thiết lập để sử dụng .net 3.5.

Vì vậy, đó sẽ là một lỗi trong khuôn khổ .NET hoặc tôi đang làm điều gì sai?

Edit: Khi tôi truy vấn Encoding.Default trong cửa sổ ngay khi đang chạy thử nghiệm của tôi, tôi có được điều này:

?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

Giả sử bạn đang sử dụng bàn phím người Anh, điều gì sẽ xảy ra nếu bạn nhập ±, § hoặc € như một phần của chuỗi (tất cả được tìm thấy trên bàn phím tiếng Anh)? Nếu những lỗi này không thành công, thì vấn đề chắc chắn với mã hóa 7 vs 8 bit, vì tất cả các ký tự này đều có mã trên 128 (tức là sử dụng 8 bit) và do đó không thể xử lý chính xác với mã hóa mặc định, , là Latin1 hoặc một số biến thể của nó. Có cách nào để thay đổi mã hóa thành UTF8 không? –

+0

Có vẻ như vấn đề với ký tự bảng được mã hóa dưới dạng ký tự ASCII 'mở rộng', chỉ có thể hiểu được nếu bạn biết trang mã được sử dụng (rõ ràng là mật khẩu băm sẽ không bao gồm trang mã được sử dụng để làm cho nó), do đó, phương pháp mã hóa có thể được từ chối một cách chính xác các ký tự được mã hóa không rõ ràng. UTF8 có vẻ giống như giải pháp đúng. – David

+0

Xin chào các bạn, cảm ơn các bạn đã góp ý. @Aleks - Tôi đã thêm ba ký tự sau: "± § €" vào chuỗi thử nghiệm của tôi và tất cả đều vượt qua bài kiểm tra. BTW bàn phím của tôi là tiếng Anh (Ireland) – lukk

Trả lời

2

tôi đã trải qua một cái gì đó tương tự với asp, tôi quản lý để có được xung quanh vấn đề này bằng cách sử dụng cấu hình sau.

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

Theo hiểu biết của tôi làm việc thẻ toàn cầu tương tự cho WCF khi bạn thiết lập

<serviceHostingEnvironment aspNetCompatibilityEnabled="true"/> 

Cập nhật: Chỉ cần kiểm tra MSDN ở dưới cùng của trang nó khẳng định như sau:

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.

Các vấn đề liên quan