POST XML 文件到页面,为什么C#要用UTF-8读取,而ASP要用GB2312读取?

evlon 2005-08-08 05:14:29
default.aspx
----------------------
private void Page_Load(object sender, System.EventArgs e)
{
string url1 = "http://localhost/Test.asp";
string url2 = "http://localhost/Test.aspx";

string data =
@"<?xml version=""1.0""?>
<params>
<action>createService</action>
<paramT>中国</paramT>
</params>
";
string strRet = PostXmlToUrl(url1,data);
Response.Write(strRet);
string strRet = PostXmlToUrl(url2,data);
Response.Write(strRet);

Response.End();
}

protected string PostXmlToUrl(string url,string data)
{
HttpWebRequest hwr = (HttpWebRequest)HttpWebRequest.Create(url);
hwr.Method = "POST";

Stream stream = hwr.GetRequestStream();

StreamWriter sw = new StreamWriter(stream,System.Text.Encoding.UTF8);
sw.Write(data);
sw.Close();

stream = hwr.GetResponse().GetResponseStream();

StreamReader sr = new StreamReader(stream,System.Text.Encoding.UTF8);
string ret = sr.ReadToEnd();
sr.Close();

return ret;

}

===================

test.aspx
------------------------------
private void Page_Load(object sender, System.EventArgs e)
{
byte[] buf = Request.BinaryRead(Request.ContentLength);
string str = System.Text.Encoding.GetEncoding("utf-8").GetString(buf);
Response.Write(str);
Response.End();
}

===========================================

test.asp
----------------------------------
<%

dim buf ,str
dim ms
buf = Request.binaryRead(Request.TotalBytes)
str = Bytes2bStr(buf)
Response.Write(str)
Response.End()

'' Byte流到Char流的转换函数
'' Code By:evlon
'' 参考:忘记了
Function Bytes2BSTR(vin)
Dim ms,strRet

Set ms = Server.CreateObject("ADODB.Stream") '建立流对象
ms.Open '默认 adTypeText
ms.WriteText vin '把vin写入流对象中

ms.Position = 0 '设置流对象的起始位置是0 以设置Charset属性
ms.Charset = "gb2312" '设置流对象的编码方式为GB2312
ms.Position = 1 '设置流对象的起始位置是1 不知道为什么是1,如果是0,则前面有?出现

strRet = ms.ReadText '取字符流
ms.close '关闭流对象
Set ms = nothing

Bytes2bStr = strRet

End Function

%>

================================================================
注意
ms.Charset = "gb2312" 为什么?

...全文
796 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
aniua 2005-08-12
  • 打赏
  • 举报
回复
至少有三种以上办法,可以把二进制数据(比如您从ASP的Request.BinaryRead方法得到的数据)转换为字符串。

第一种:使用VBS的MultiByte 方法

实例:

Function SimpleBinaryToString(Binary)
'SimpleBinaryToString converts binary data (VT_UI1 | VT_ARRAY Or MultiByte string)
'to a string (BSTR) using MultiByte VBS functions
Dim I, S
For I = 1 To LenB(Binary)
S = S & Chr(AscB(MidB(Binary, I, 1)))
Next
SimpleBinaryToString = S
End Function

这个方法非常简单明了,但是处理大数据流时,比较慢。
建议只用来处理100KB以下的数据。
下面的这个类似的方法,性能稍微好些:
Function BinaryToString(Binary)
'Antonin Foller, http://www.pstruh.cz
'Optimized version of a simple BinaryToString algorithm.

Dim cl1, cl2, cl3, pl1, pl2, pl3
Dim L
cl1 = 1
cl2 = 1
cl3 = 1
L = LenB(Binary)

Do While cl1<=L
pl3 = pl3 & Chr(AscB(MidB(Binary,cl1,1)))
cl1 = cl1 + 1
cl3 = cl3 + 1
If cl3>300 Then
pl2 = pl2 & pl3
pl3 = ""
cl3 = 1
cl2 = cl2 + 1
If cl2>200 Then
pl1 = pl1 & pl2
pl2 = ""
cl2 = 1
End If
End If
Loop
BinaryToString = pl1 & pl2 & pl3
End Function
BinaryToString方法比SimpleBinaryToString方法性能高20倍。建议用来处理2MB以下的数据。
第二种方法:使用ADODB.Recordset
ADODB.Recordset 可以让你支持几乎所有VARIANT支持的数据类型,你可以用它在string和
binary之间转换。
Function RSBinaryToString(xBinary)
'Antonin Foller, http://www.pstruh.cz
'RSBinaryToString converts binary data (VT_UI1 | VT_ARRAY Or MultiByte string)
'to a string (BSTR) using ADO recordset

Dim Binary
'MultiByte data must be converted To VT_UI1 | VT_ARRAY first.
If vartype(xBinary)=8 Then Binary = MultiByteToBinary(xBinary) Else Binary = xBinary

Dim RS, LBinary
Const adLongVarChar = 201
Set RS = CreateObject("ADODB.Recordset")
LBinary = LenB(Binary)

If LBinary>0 Then
RS.Fields.Append "mBinary", adLongVarChar, LBinary
RS.Open
RS.AddNew
RS("mBinary").AppendChunk Binary
RS.Update
RSBinaryToString = RS("mBinary")
Else
RSBinaryToString = ""
End If
End Function
RSBinaryToString 没有什么限制--除了物理内存之外。这种处理方式是MultiByte方式的100倍!你可以用它来处理高达100MB的数据! 这种转换方式,你也可以用来把MultiByte strings转换为String。下面这个方法把MultiByte strings转换为Binary:Function MultiByteToBinary(MultiByte)
'© 2000 Antonin Foller, http://www.pstruh.cz
' MultiByteToBinary converts multibyte string To real binary data (VT_UI1 | VT_ARRAY)
' Using recordset
Dim RS, LMultiByte, Binary
Const adLongVarBinary = 205
Set RS = CreateObject("ADODB.Recordset")
LMultiByte = LenB(MultiByte)
If LMultiByte>0 Then
RS.Fields.Append "mBinary", adLongVarBinary, LMultiByte
RS.Open
RS.AddNew
RS("mBinary").AppendChunk MultiByte & ChrB(0)
RS.Update
Binary = RS("mBinary").GetChunk(LMultiByte)
End If
MultiByteToBinary = Binary
End Function
第三种:使用ADODB.Stream这种方式是比较常用的:'Stream_BinaryToString Function
'2003 Antonin Foller, http://www.pstruh.cz
'Binary - VT_UI1 | VT_ARRAY data To convert To a string
'CharSet - charset of the source binary data - default is "us-ascii"
Function Stream_BinaryToString(Binary, CharSet)
Const adTypeText = 2
Const adTypeBinary = 1

'Create Stream object
Dim BinaryStream 'As New Stream

evlon 2005-08-12
  • 打赏
  • 举报
回复
原来是方法错误,
流中有字符集格式如:UTF-8:FF FE

在网上找到相关解决方法如下:
=============================================
'Stream_BinaryToString Function
'2003 Antonin Foller, http://www.pstruh.cz
'Binary - VT_UI1 | VT_ARRAY data To convert To a string
'CharSet - charset of the source binary data - default is "us-ascii"
Function Stream_BinaryToString(Binary, CharSet)
Const adTypeText = 2
Const adTypeBinary = 1

'Create Stream object
Dim BinaryStream 'As New Stream
Set BinaryStream = CreateObject("ADODB.Stream")

'Specify stream type - we want To save text/string data.
BinaryStream.Type = adTypeBinary

'Open the stream And write text/string data To the object
BinaryStream.Open
BinaryStream.Write Binary


'Change stream type To binary
BinaryStream.Position = 0
BinaryStream.Type = adTypeText

'Specify charset For the source text (unicode) data.
If Len(CharSet) > 0 Then
BinaryStream.CharSet = CharSet
Else
BinaryStream.CharSet = "us-ascii"
End If

'Open the stream And get binary data from the object
Stream_BinaryToString = BinaryStream.ReadText
End Function
iloveyour 2005-08-10
  • 打赏
  • 举报
回复
mark
evlon 2005-08-10
  • 打赏
  • 举报
回复
现在改成这个样子了:
==================================
<%
dim buf ,str
dim ms
str = "aaa"
buf = Request.binaryRead(Request.TotalBytes)
str = Bytes2bStr(buf)
call WriteFileLog("log\log.txt",str)
Response.Write(str)

Response.End()

'' Byte流到Char流的转换函数
'' Code By:evlon
'' 参考:忘记了
Function Bytes2BSTR(vin)
Dim ms,strRet

Set ms = Server.CreateObject("ADODB.Stream") '建立流对象
ms.Open '默认 adTypeText
ms.WriteText vin '把vin写入流对象中

ms.Position = 0 '设置流对象的起始位置是0 以设置Charset属性
ms.Charset = "utf-8" '设置流对象的编码方式为utf-8
ms.Position = 8 '设置流对象的起始位置是8 不知道为什么是8,如果是0,则前面有?出现
' ms.Charset = "gb2312" '设置流对象的编码方式为GB2312
' ms.Position = 8 '设置流对象的起始位置是8 不知道为什么是8,如果是0,则前面有?出现

strRet = ms.ReadText '取字符流
ms.close '关闭流对象
Set ms = nothing

Bytes2bStr = strRet

End Function

'''将信息写到一个文本文件里
Sub WriteFileLog(sFilename,sMsgContent)
'''参数说明:
'' sMsgContent:信息内容
'' sFilename:相对当前目录的文件名
Dim sMsg,str ,arr
Dim fs,sPage,sFile
Dim sCopName,sDeptName,sUserName,sPath
Set fs=Server.CreateObject("Scripting.FileSystemObject")

sMsg=cstr(now) & " " & chr(13) & chr(10) & sMsgContent
if left(sFileName,1)<>"\" then
sFileName="\" & sFileName
end if

sPath=Server.MapPath("./")

arr=split(sFileName,"\")
for each str in arr
if(trim(str)<>"") then
sPath = sPath & "\" & str
if instr(str,".")>0 then
'''先判断文件是否存在,如果不存则新建一个
IF NOT fs.FileExists(sPath) Then
fs.CreateTextFile sPath,True
End IF
else
IF NOT fs.FolderExists(sPath) Then
fs.CreateFolder sPath
End IF
end if
end if
next

Set sFile=fs.OpenTextFile(sPath,8)
sFile.WriteLine sMsg
Set sFile=Nothing
Set fs=Nothing
End Sub


%>
====================
运行结果
2005-8-10 9:32:35
<?xml version="1.0" encoding="utf-8"?>
<params>
<Action>createService</Action>
<ServiceGuid>hb0311002_02</ServiceGuid>
<paramT>30</paramT>
<paramS>0</paramS>
<paramC>0</paramC>
<paramOther>aaa=5</paramOther>
<hashcode>52D75B704990233DB8DC727E406A6E09</hashcode>
<timestamp>63259263155578125018120</timestamp>
</params>
2005-8-10 9:32:35
<?xml version="1.0" encoding="utf-8"?>
<params>
<Action>changeService</Action>
<sequenceId>2342134124123412124124124</sequenceId>
<ServiceGuid>hb0311002_02</ServiceGuid>
<paramT>30</paramT>
<paramS>0</paramS>
<paramC>0</paramC>
<paramOther>aaa=4444;b=我来这时在是什么时的事情了</paramOther>
<hashcode>B390FFB9A5128BD8BA281E03E2506774</hashcode>
<timestamp>632592631556562500614402</timestamp>
</params>
2005-8-10 9:32:35
<?xml version="1.0" encoding="utf-8"?>
<params>
<Action>pauseService</Action>
<sequenceId>2342134124123412124124124</sequenceId>
<hashcode>3DF9CDA8374037EC93741FE2046D6602</hashcode>
<timestamp>632592631556718750748735</timestamp>
</params>
2005-8-10 9:32:35
<?xml version="1.0" encoding="utf-8"?>
<params>
<Action>continueService</Action>
<sequenceId>2342134124123412124124124</sequenceId>
<hashcode>C8B73AB4FEDCA5F1C055DFF8EE3677A4</hashcode>
<timestamp>632592631556718750279378</timestamp>
</params>
2005-8-10 9:32:35
<?xml version="1.0" encoding="utf-8"?>
<params>
<Action>cancelService</Action>
<sequenceId>2342134124123412124124124</sequenceId>
<hashcode>01E0242AAF05BD2E56B181E51372B978</hashcode>
<timestamp>63259263155687500054464</timestamp>
</params>
evlon 2005-08-10
  • 打赏
  • 举报
回复
自已顶
brando_beat 2005-08-10
  • 打赏
  • 举报
回复
evlon 2005-08-10
  • 打赏
  • 举报
回复
用utf-8取,

ms.Position = 8 '设置流对象的起始位置是8

不知道为什么了?
反正现在没有乱码了


evlon 2005-08-09
  • 打赏
  • 举报
回复
我发送页
StreamWriter sw = new StreamWriter(stream,System.Text.Encoding.UTF8);
是用的UTF8编码

楼上的取的哪个页面,我取得就是我的发送页面呀。且我用的是UTF8编码呀
evlon 2005-08-09
  • 打赏
  • 举报
回复
顶有分,大家帮忙顶呀
lovebanyi 2005-08-08
  • 打赏
  • 举报
回复
跟你取的哪个页面有关系啊
tigerwen01 2005-08-08
  • 打赏
  • 举报
回复
gb2312,UTF-8都是编码集,参考以下说明:

UTF8还是GB2312?
早些年上网的朋友都知道,NS或IE浏览器早期的版本并不支持多国语言的浏览,如果想浏览繁体中文、日文等外文网站还需要一个如“中文之星”或“四通立方”的外挂软件,后来浏览器逐步发展升级,到目前为止,几乎所有浏览器都支持多国语言字符,可以浏览任意国家、语言的网站。Blog的出现,特别是Trackback的出现,使网络国际化的行为由被动的浏览信息向主动式的交互信息过渡,然而新的语言障碍问题又出现了...

问题主要出在Blog的Trackback(引用)、Ping(通告)、Notification(通知书)等交互具有的功能上。以前我们在理解和应用网络上的交互主要局限在C-S范围之内,也就是客户(个人)与服务器(网站)之间的信息交互,例如:在网络上发布一篇文章或回复一个论坛帖子,一般来讲这样的交互很少会出现语言不兼容的问题。然而Blog中的Trackback等的交互方式不只是C-S的,它还是S-S(Blog网站之间)的,甚至是多重的,例如在发布一篇文章的时候,你可以同时选择让它同时发布在一个或多个不同的Blog上,或者给指定的人发出更新通知,也可以让更多的人预订、收录你的RSS内容更新信息。Blog的交互方式更多、更灵活,当然,这种交互并非没有限制,语言编码是一个很大障碍,如果你的Blog系统编码是中文简体的GB2312,那么所有Trackback、Ping的交互对象就只能限于国内采用GB2312编码的用户,你的Blog也就无法与台湾、日本等采用非GB2312编码的用户实现交互。

比较好的解决办法是采用UTF-8编码,虽然采用UTF-8编码回多占用一些空间(一个汉字需3个字节),但国际化问题总算解决了,UTF-8兼容GB2312、BIG5、EUC-JP等多种国家的语言编码,经测试,采用UTF-8编码的Blog之间的各种交互、通讯没有任何问题。事实上90%以上的台湾Blog都已经舍弃了BIG5,而采用UTF-8的编码方式,而大陆的Blog几乎还都是GB2312编码,看来台湾在国际化方面还是相当领先的。

前几日,我将自己的Blog从GB2312编码转为了UTF-8编码,Trackback和Ping了几个台湾朋友的Blog,没有发现问题。看来“国际化”的问题已经解决了,但随之而来有出现了新的问题,我的Blog与国内GB2312编码的Blog又无法交互了,当然这是必然的。我Ping到online-edu.org(网站采用GB2312编码)上的信息都成了乱码。

我想问题到此,已经不是技术层面的了。如果你的站点或Blog有国际化交流的需求,可通过采用UTF-8编码的方式来解决,如果没有这个需求,采用GB2312也无大碍。在用户看来都是一样的,编码只是后台的东西。不过我希望Blogger们最好都采用UTF-8编码,因为你的Blog有了Trackback和Ping,它们可是持有国际航班的机票,如果只在本国转悠,确实很浪费。


Part1第一部分: 相信大家找得到该书的源代码部分 也就是这部分内容 因此我便无偿奉送 让大家下载试试。 若感觉可以方可继续下载电子书部分。 1.本书1~21章所附代码的运行环境 操作系统:Windows Server 2003或Windows XP Professional 开发环境:Microsoft Visual Studio 2005 数据库:SQL Server 2005 Web服务器:IIS 5.1及以上版本 2.本书所附光盘范例 第1章(\Chapter 01) 示例描述:本章演示ASP.NET 2.0网站的预编译以及学习ASP.NET 2.0的前置知识。 WebSite文件夹 创建的ASP.NET 2.0 Web站点。 www文件夹 第一个用C#开发的Web应用程序。 bianyi.bat 编译网站的批处理文件。 form.html 表单范例。 css.html CSS范例。 第3章(\Chapter 03) 示例描述:本章介绍C# 2.0程序设计基础。 3-01.cs 第一个C#程序。 3-02.cs 不导入命名空间来改写程序3-01.cs。 3-03.cs ReadLine()方法读数据。 3-04.cs 常量的使用。 3-05.cs 整型类型的使用。 3-06.cs 结构类型的使用。 3-07.cs 枚举类型的使用。 3-08.cs 用一个输入参数通过值传递一个变量给一个方法。 3-09.cs 一维数组的使用。 3-10.cs 使用代理类型。 3-11.cs 使用接口。 3-12.cs 装箱操作。 3-13.cs 字符串操作。 3-14.cs if语句的使用。 3-15.cs switch语句的使用。 3-16.cs while语句的使用。 3-17.cs do-while语句的使用。 3-18.cs for语句的使用。 3-19.cs 异常捕获:try-catch语句的使用。 3-20.cs 异常捕获:try-finally语句的使用。 3-21.cs 异常捕获:try-catch-finally语句的使用。 3-22.cs get和set对属性的值进行读写操作。 3-23.cs 方法的使用。 3-24.cs 继承演示。 3-25.cs 多态性演示。 第4 章(\Chapter 04) 示例描述:本章学习ASP.NET 2.0页面基本对象。 4-01.aspx aspx页面中添加一个Lable标签。 4-02.aspx 读出Application的属性值。 4-03.aspx 读出SessionID的值。 4-04.aspx 创建Session对象。 4-05.aspx 读取传递的Session值并显示。 4-06.aspx 使用Response对象的Write()方法。 4-07.aspx 使用Response对象的End()方法。 4-08.html 以post方式提交数据到4-08.aspx的表单。 4-08.aspx 接收表单数据并进行处理。 4
利用wsdl.exe生成webservice代理类: 根据提供的wsdl生成webservice代理类 1、开始->程序->Visual Studio 2005 命令提示 2、输入如下红色标记部分 D:\Program Files\Microsoft Visual Studio 8\VC>wsdl /language:c# /n:TestDemo /out:d:\Temp\TestService.cs D:\Temp\TestService.wsdl 在d:/Temp下就会产生一个TestService.cs 文件 注意:D:\Temp\TestService.wsdl 是wsdl路径,可以是url路径:http://localhost/Temp/Test.asmx?wsdl wsdl参数说明: wsdl.exe ... - 选项 - - 指向 WSDL 协定、XSD 架构或 .discomap 文档的 URL 或路径。 /nologo 取消显示版权标志。 /language: 用于生成的代理类的语言。请从“CS”、“VB”、“JS”、“VJS”、 “CPP”中选择,或者为实现 System.CodeDom.Compiler.CodeDomProvider 的类提供一个完全限定的名称。默认语言为“CS”(CSharp)。 缩写形式为“/l:”。 /sharetypes 打开类型共享功能。此功能针对不同服务之间共享 的相同类型(命名空间、名称和网络签名必须相同) 创建一个具有单一类型定义的代码文件。 请使用 http:// URLs 作为命令行参数来引用 服务,或为本地文件创建一个 discomap 文档。 /verbose 指定 /sharetypes 开关时显示额外信息。 缩写形式为“/v”。 /fields 生成字段而非属性。缩写形式为“/f”。 /order 为粒子成员生成显式顺序标识符。 /enableDataBinding 在所有生成的类型上实现 INotifyPropertyChanged 接口, 以启用数据绑定。缩写形式为“/edb”。 /namespace: 生成的代理或模板的命名空间。默认命名空间 为全局命名空间。缩写形式为“/n:”。 /out: 生成的代理代码的文件名或目录路径。默认文件名是从 服务名派生的。缩写形式为“/o:”。 /protocol: 重写要实现的默认协议。请从“SOAP”、“SOAP12”、 “HttpGet”、“HttpPost”中选择。 /username: /password: /domain: 连接到要求身份验证的服务器时使用的凭据。 缩写形式为“/u:”、“/p:”和“/d:”。 /proxy: 用来处理 HTTP 请求的代理服务器的 URL。 默认为使用系统代理服务器设置。 /proxyusername: /proxypassword: /proxydomain: 连接到要求身份验证的代理服务器时使用的凭据。 缩写形式为“/pu:”、“/pp:”和“/pd:”。 /appsettingurlkey: 在代码生成中用来读取 URL 属性的 默认值的配置项。默认为不从配置 文件读取。缩写形式为“/urlkey:”。 /appsettingbaseurl: 计算 URL 段时使用的基 URL。 还必须指定 appsettingurlkey 选项。URL 段是 从 appsettingbaseurl 计算 WSDL 文档中的 URL 的相对 URL 的结果。缩写形式为“/baseurl:”。 /parsableerrors 输出错误,其格式与编译器报告的格式类似。 - 高级 - /server 服务器开关已被否决。请改用 /serverInterface。 使用基于协定的 ASP.NET,为 Xml Web Services 实现 生成抽象类。默认情况下,生成客户端

62,074

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术交流专区
javascript云原生 企业社区
社区管理员
  • ASP.NET
  • .Net开发者社区
  • R小R
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

.NET 社区是一个围绕开源 .NET 的开放、热情、创新、包容的技术社区。社区致力于为广大 .NET 爱好者提供一个良好的知识共享、协同互助的 .NET 技术交流环境。我们尊重不同意见,支持健康理性的辩论和互动,反对歧视和攻击。

希望和大家一起共同营造一个活跃、友好的社区氛围。

试试用AI创作助手写篇文章吧