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
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? –
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
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