.net - WCF 中密码不能包含英镑?

标签 .net wcf frameworks encoding passwords

我是否发现了 .NET 框架中的错误或者我做错了什么?

这是这个故事。

我昨天尝试在 WCF channel 上设置密码,如下所示:

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)) 不喜欢英镑符号 (£)。

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

    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.Default”时,EncodingRightGetBytes 工作正常。与“Encoding.UTF8。”...

谷歌搜索这个方法名称会返回很少的链接,其中之一是: 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

最佳答案

我在 asp 中遇到过类似的情况,我设法通过使用以下配置解决了该问题。

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

据我所知,当您设置时,全局化标记对于 WCF 的作用是相同的

<serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>

更新:刚刚检查MSDN页面底部注明以下内容:

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.

关于.net - WCF 中密码不能包含英镑?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7106204/

相关文章:

.net - 牌照问题

c# - 代码虚拟化混淆会导致最大 CPU 吗?

wcf - 使用 WCF 代理的依赖注入(inject)

wpf - WCF 到 WPF 类 INotifyPropertyChanged 怎么样

frameworks - 更新代码以使用 Cocoa Touch 框架而不是 iOS 通用框架

javascript - 带有应用程序展示的着陆页

.net - 在 Visual Studio 调试 session 期间查找当前目录?

.net - 扩展方法类不能嵌套有充分的理由吗?

c# - WCF WebInvoke JSON 反序列化失败 - 400 错误请求

c# - 在一个 Nuget 包中定位 .Net Core Framework 和完整的 .Net 4.5/4.6 Framework