Czy wykryłem błąd w strukturze .NET lub czy robię coś nie tak?hasło nie może zawierać funta brytyjskiego w WCF?
Oto historia.
starałem się ustawić hasło na kanale WCF wczoraj tak:
channelFactory.Credentials.UserName.UserName = credentials.Username;
channelFactory.Credentials.UserName.Password = credentials.Password;
a następnie wywołać metody usługi sieci Web, kiedy mam ten błąd:
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)
Więc zacząłem szukać na nim i dzienniki pokazują, że nie dostaję się nawet do serwera. Okazuje się, że metoda ramowa .NET, która zgłasza wyjątek (System.Net.BasicClient.EncodingRightGetBytes (String rawString)) nie lubi brytyjskiego znaku funta (£).
skopiowane metodę z odbłyśnikiem i pisał test szybki jednostkową i funt jest jedyną postacią, która nie robi jak z wszystkim mogę wpisać na klawiaturze:
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;
}
To jest mój testów jednostkowych w celu sprawdzenia ta metoda:
[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));
}
}
}
Jak widać EncodingRightGetBytes porównuje dwa ciągi i są one różne, jeśli oryginalny łańcuch (rawString) zawiera funta brytyjskiego.
EncodingRightGetBytes działa dobrze, kiedy należy wymienić z ...
Googling nazwa ta metoda przynosi z powrotem bardzo kilka linków, jednym z nich jest to „Encoding.Default.” „Encoding.UTF8.”: http://support.microsoft.com/kb/943511
Używam VS 2010 z zestawem projektów asp.net do używania .net 3.5.
Czyli to byłby błąd w strukturze .NET lub czy robię coś nie tak?
Edit: Kiedy kwerendy Encoding.Default w okienku bezpośrednim podczas jazdy mój test uzyskać to:
?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
Zakładając, że używasz brytyjskiej klawiatury, co się stanie, jeśli wpiszesz ±, § lub € jako część ciągu (wszystkie zostaną znalezione na klawiaturze w Wielkiej Brytanii)? Jeśli te również się nie powiodą, to problem jest zdecydowanie z kodowaniem 7 lub 8 bitowym, ponieważ wszystkie te znaki mają kody powyżej 128 (tj. Używają 8 bitów) i dlatego nie mogą być przetwarzane poprawnie z domyślnym kodowaniem, które, najprawdopodobniej , jest Latin1 lub jego pewną odmianę. Czy istnieje sposób na zmianę kodowania na UTF8? –
To brzmi jak problem z zakodowanym znakiem funta jako "rozszerzonym" znakiem ASCII, który może mieć sens jedynie, jeśli znasz stronę kodową, która była używana (oczywiście hash hasła nie zawiera strony kodowej używanej do make it), więc metoda kodowania może słusznie odrzucić niejednoznacznie zakodowane znaki. UTF8 brzmi jak właściwe rozwiązanie. – David
Witajcie, dziękuję za komentarze. @Aleks - Dodałem te trzy znaki: "± § €" do mojego ciągu testowego i wszystkie zdały test. BTW moja klawiatura to angielski (Irlandia) – lukk