C# MonoTouch-UIDevice.CurrentDevice.Name-UTF8
我们注意到,在MonoTouch中使用C# MonoTouch-UIDevice.CurrentDevice.Name-UTF8,c#,.net,utf-8,xamarin.ios,C#,.net,Utf 8,Xamarin.ios,我们注意到,在MonoTouch中使用UIDevice.CurrentDevice.Name时,UTF8字符不能正确显示 如果你使用一些特殊的字符,比如按住iPad键盘上的撇号键,它就会被称为“iPad2??”。(抱歉,不知道在windows中显示这些字符的等效项) 是否有推荐的解决方法来获取正确的文本?我们不介意自己转换成UTF8。我还试着从UITextField模拟它,结果很好——没有UTF8问题 这导致问题的原因是我们正在将此文本发送到web服务,这导致了XML解析问题 下面是XmlWri
UIDevice.CurrentDevice.Name
时,UTF8字符不能正确显示
如果你使用一些特殊的字符,比如按住iPad键盘上的撇号键,它就会被称为“iPad2??”。(抱歉,不知道在windows中显示这些字符的等效项)
是否有推荐的解决方法来获取正确的文本?我们不介意自己转换成UTF8。我还试着从UITextField模拟它,结果很好——没有UTF8问题
这导致问题的原因是我们正在将此文本发送到web服务,这导致了XML解析问题
下面是XmlWriter代码的片段(\u parser.WriteRequest
):
TextWriter是从以下位置传入的:
public Response MakeRequest(Request request)
{
var httpRequest = CreateRequest(request);
WriteRequest(httpRequest.GetRequestStream(), request);
using (var httpResponse = httpRequest.GetResponse() as HttpWebResponse)
{
using (var responseStream = httpResponse.GetResponseStream())
{
var response = new Response();
ReadResponse(response, responseStream);
return response;
}
}
}
private void WriteRequest(Stream requestStream, Request request)
{
if (request.Type == null)
{
throw new InvalidOperationException("Request Type was null!");
}
if (_logger.Enabled)
{
var builder = new StringBuilder();
using (var writer = new StringWriter(builder, CultureInfo.InvariantCulture))
{
_parser.WriteRequest(writer, request);
}
_logger.Log("REQUEST: " + builder.ToString());
using (requestStream)
{
using (StreamWriter writer = new StreamWriter(requestStream))
{
writer.Write(builder.ToString());
}
}
}
else
{
using (requestStream)
{
using (StreamWriter writer = new StreamWriter(requestStream))
{
_parser.WriteRequest(writer, request);
}
}
}
}
\u记录器
写入控制台。WriteLine
,如果在调试模式下启用Request
只是一个带有属性的存储类,很抱歉容易与HttpWebRequest
混淆
我看到了??在XCode的控制台和MonoDevelop的控制台中。我还假设服务器也奇怪地接收到它们,因为我得到了一个错误。使用带有相同奇怪字符的UITextField.Text
,而不是设备描述,可以正常工作,不会出现任何问题。这让我觉得设备描述就是罪魁祸首
编辑:这将修复它-
Encoding.UTF8.GetString(Encoding.ASCII.GetBytes(UIDevice.CurrentDevice.Name))代码>好的,我想我知道问题所在。您正在创建一个StringWriter
,它总是将其编码报告为UTF-16(除非您重写encoding
属性)。然后从StringWriter
(以
开头)获取字符串,并将其写入默认为UTF-8的StreamWriter
。这种混合编码导致了这个问题
最简单的方法是更改代码,将流
直接传递给XmlWriter
-aMemoryStream
(如果您确实需要),或者只需请求流
)。通过这种方式,XmlWriter
可以声明它使用的是它实际上正在写入二进制数据的确切编码——您没有中间步骤来搞乱事情
或者,您可以创建StringWriter
的子类,该子类允许您指定编码。请参阅以获取一些示例代码。MonoTouch只需调用它从调用UIDevice.CurrentDevice.Name
中收到的值。与大多数string
一样,它是从所有绑定中的NSString
创建的
这应该会给你一个字符串,你可以看到它(没有?
),所以我不能排除一个bug
你能告诉我们这个设备的确切名称吗?如果是这样,请打开a,我们将检查这种可能性。不清楚“UTF8字符”是什么意思-UTF-8是将字符编码为二进制的一种方法。这不是一个字符集。如何创建XML?在MonoTouch中使用XmlWriter,服务器未知(第三方)。让我更清楚地说,UITextField.Text
会按预期返回字符吗?来自UIDevice.CurrentDevice.Name
的字符,我假设这意味着“未知字符”。Jon,我不知道你用过MonoTouch。我没有做过MonoTouch的开发,但我以前见过很多编码错误。您如何准确地使用XmlWriter
。请出示你的密码。当您说“we get?characters”时,您的意思是web服务接收到的字符,还是在调试器中看到的字符,或者其他什么?您是否尝试记录字符串中每个字符的Unicode代码点?通常,追踪这类问题只是找出数据丢失的位置。我想知道解决方法是否是UTF8
现在显式链接到了。例如,如果您稍后再次请求Name
(没有编码调用),会发生什么情况?或者MD调试器显示了什么?我尝试了一下,没有运气。我不确定这是否是一个链接问题。中间步骤是让我们有一个StringBuilder
传递给我们的记录器,我可以在我所有的writer上将编码设置为UTF8吗?@Jonathan.Peppers:请参阅我答案的最后一段。尝试了你的Utf8StringWriter
,没有解决它,但为了完整性保留了它。见我的编辑上面的工作。这是一个有效的解决方案吗?这看起来像是我应该提交给Xamarin的东西吗?@Jonathan.Peppers:绝对不是-这只是将其限制为ASCII。你真的应该把字符记录在XML中,并且仔细观察web服务到底是什么(使用Wireshark)。是的,我害怕的是什么。但是如果文本是从Xamarin的末尾出来的ASCII码,我就不能做很多其他的事情来修复它,对吗?我认为@poupou的输入会有所帮助。按住iPad键盘上的撇号键。它将给你4个选项,两个曲线撇号是引起问题的。您只需在控制台中打印出UIDevice.CurrentDevice.Name
即可查看我看到的内容。我将我的iPad重命名为Neptune“a”,它工作正常(我在控制台上,在MD调试器内看到它工作正常…)。这是一个长期的尝试,但你能尝试不链接(即不链接)你的应用程序吗?以防万一一些代码被从应用程序中剥离(但不是从我的单元测试中剥离)。好的,我也要试试@jon打印整数值的想法。我在新项目中复制这一点有困难,所以我猜这是我的错,jon Skeet认为这只是一个标准的.Net编码问题是正确的。谢谢你的帮助,等我弄明白了我会发回的。我想补充一点,我的困惑在于??在控制台中显示,但该值在C#中实际上是正确的。在MonoDevelop的调试器中也是正确的。似乎只有UTF8 wh的缺失
public Response MakeRequest(Request request)
{
var httpRequest = CreateRequest(request);
WriteRequest(httpRequest.GetRequestStream(), request);
using (var httpResponse = httpRequest.GetResponse() as HttpWebResponse)
{
using (var responseStream = httpResponse.GetResponseStream())
{
var response = new Response();
ReadResponse(response, responseStream);
return response;
}
}
}
private void WriteRequest(Stream requestStream, Request request)
{
if (request.Type == null)
{
throw new InvalidOperationException("Request Type was null!");
}
if (_logger.Enabled)
{
var builder = new StringBuilder();
using (var writer = new StringWriter(builder, CultureInfo.InvariantCulture))
{
_parser.WriteRequest(writer, request);
}
_logger.Log("REQUEST: " + builder.ToString());
using (requestStream)
{
using (StreamWriter writer = new StreamWriter(requestStream))
{
writer.Write(builder.ToString());
}
}
}
else
{
using (requestStream)
{
using (StreamWriter writer = new StreamWriter(requestStream))
{
_parser.WriteRequest(writer, request);
}
}
}
}