密码在WCF中不能包含英镑?

时间:2011-08-18 10:50:26

标签: .net wcf frameworks encoding passwords

我是否在.NET框架中发现了一个错误,或者我做错了什么?

这是故事。

我昨天试图在WCF频道上设置密码:

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

然后在出现此错误时调用Web服务方法:

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)

所以我开始关注它并且日志显示我甚至没有达到服务器的程度。事实证明,抛出异常的.NET框架方法(System.Net.BasicClient.EncodingRightGetBytes(String rawString))不喜欢英镑符号(£)。

我从反射器复制了这个方法并编写了一个快速的单元测试,而pound是我在键盘上输入的唯一一个不喜欢的字符:

    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)包含英镑,它们会有所不同。

当我用“Encoding.UTF8”替换“Encoding.Default。”时,EncodingRightGetBytes工作正常。...

谷歌搜索这个方法名称会带回很少的链接,其中一个是这样的: http://support.microsoft.com/kb/943511

我正在使用VS 2010,并将asp.net项目设置为使用.net 3.5。

那么这将是.NET框架中的错误还是我做错了什么?

编辑: 当我在运行测试时在立即窗口中查询Encoding.Default时,我得到了这个:

?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 个答案:

答案 0 :(得分:2)

我经历过与asp类似的事情,我设法通过使用以下配置解决了这个问题。

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

据我所知,在设置

时,全球化标签对WCF的作用相同
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>

更新:刚刚检查了页面底部的MSDN,它说明了以下内容:

  

ASP.NET配置语言允许您指定文化   个人服务。 WCF不支持该配置   除ASP.NET兼容模式外的设置。本地化WCF   不使用ASP.NET兼容模式的服务,编译   服务类型为特定于文化的程序集,并具有单独的   针对每种文化特定组装的特定文化终点。