关于SoapFormatter反序列化的问题

Kyle-soft 2002-12-29 03:41:07
SoapFormatter在普通的应用程序可以运行的很好,
但是我把他放到WebService中去使用的是后总是报告错误.
请高手指教.!
以下是我在普通应用程序中使用的情况:
using System;
using System.Net;
using System.IO;
using System.Text;
using System.Web;
using System.Xml;
using System.Xml.Xsl;
using System.Runtime.Serialization.Formatters.Soap;
using System.Runtime.Serialization.Formatters.Binary;

class ClientPOST {
public static void Main(string[] args) {
SoapFormatter formatter = new SoapFormatter();
FileStream mstream = new FileStream(@"H:\XSchool\MSWeb\bin\tt.xml", FileMode.Open);
Test rinfo = (Test)formatter.Deserialize(mstream);
Console.WriteLine(rinfo.Name);
}
}
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://www.rookiesoft.com/webservices/")]
[Serializable()]
public class Test
{
public string Name;
public Test()
{
this.Name = "";
}
public Test(string name)
{
this.Name = name;
}
}
tt.xml中内容如下:
<SOAP-ENV:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:clr="http://schemas.microsoft.com/soap/encoding/clr/1.0" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body>
<a1:Test id="ref-1" xmlns:a1="http://schemas.microsoft.com/clr/assem/tt%2C%20Version%3D0.0.0.0%2C%20Culture%3Dneutral%2C%20PublicKeyToken%3Dnull">
<Name id="ref-3">Liaoyuan</Name>
</a1:Test>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

放到WebService中时,
SoapFormatter formatter = new SoapFormatter();
FileStream fstream = new FileStream(@"H:\XSchool\MSWeb\bin\tt.xml", FileMode.Open);
Test rinfo = (Test)formatter.Deserialize(fstream);
((ResponseInfo)objReturn).ErrorMessage += rinfo.Name;
fstream.Close();

结果在Test rinfo = (Test)formatter.Deserialize(fstream);
((ResponseInfo)这里出错,
不知道为什么, 如果我转换的是String一类的简单类型的话,没问题.
...全文
198 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
qqchen79 2003-01-10
  • 打赏
  • 举报
回复
之所以XmlSerializer会成功,是因为Binary/Soap Formatter是以对象为中心的,他们要求Serialize/Deserialize的时候对象由完全一致的定义(同一个Assembly,同一个版本,等等);而XmlSeriaizer是以Xml格式为中心的,只要Serialize/Deserialize时使用的类型在Xml格式上兼容就可以,不需要在Assembly上一致,甚至可以有不同的类型名称、名称空间等。

BTW: System.Xml.Serialization.XmlTypeAttribute不会影响SoapFormatter的运行结果,只对XmlSerializer有作用,仔细观察的话你会发现它们甚至定义在不同的namespace中。
qqchen79 2003-01-10
  • 打赏
  • 举报
回复
由于没有出错信息,所以只是根据你的代码猜测出错的可能。
如果没猜错的话,你是直接把tt.cs里面的Test类型的定义拷贝到WebService的.asmx文件里面的。在这种情况下,虽然两个类型的定义完全一致,但是.NET仍然会认为它们是两个不同的类型——因为它们定义在两个不同的Assembly里面。所以当你Deserialize的时候,.NET发现tt.xml中是tt.exe中的Test,而强制转换的结果却是WebService中定义的Test,转换失败。

正确的做法应该是:把Test的定义放在一个单独的Dll中,在tt.exe中引用该dll编译。然后把这个Dll的一份拷贝放在WebService的虚目录下的bin子目录下面。这样,两个应用引用的是同一个Test类型,就不会有问题了。
idiotzeng 2003-01-10
  • 打赏
  • 举报
回复
1、将http://schemas.microsoft.com/clr/assem/tt中的tt改为Web Services中相应的程序集名称试试

我也提到了知秋说的程序集问题呀:P
qqchen79 2003-01-10
  • 打赏
  • 举报
回复
to idiotzeng(白痴(☆☆☆☆☆☆☆☆)) :
你的名字起的不好,大家信不过你的说。:)
Kyle-soft 2003-01-10
  • 打赏
  • 举报
回复
如果qqchen79兄觉得分不够也可以到http://expert.csdn.net/Expert/topic/1310/1310299.xml去报个到!
Kyle-soft 2003-01-10
  • 打赏
  • 举报
回复
这300分给qqchen79了!
请其他几位到http://expert.csdn.net/Expert/topic/1310/1310299.xml领分
Kyle-soft 2003-01-10
  • 打赏
  • 举报
回复
前几天很忙, 没时间来研究这个问题, 今天弄了下, 正如qqchen79所说, 感谢各位! 现把我的最终代码贴出如下:
using System;
using System.IO;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Web;
using System.Web.Services;
using System.Runtime.Serialization.Formatters.Soap;

namespace TestSoapFormatter
{
/// <summary>
/// Summary description for MyService.
/// </summary>
[WebService(Namespace="http://www.rookiesoft.com/webservices/")]
public class MyService : System.Web.Services.WebService
{
public MyService()
{
//CODEGEN: This call is required by the ASP.NET Web Services Designer
InitializeComponent();
}

#region Component Designer generated code

//Required by the Web Services Designer
private IContainer components = null;

/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
}

/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if(disposing && components != null)
{
components.Dispose();
}
base.Dispose(disposing);
}

#endregion

[WebMethod]
public string Serialize()
{
string rt = "Serialize OK!";
try
{
Person person = new Person("LiaoyuanZhang", 26);
SoapFormatter formatter = new SoapFormatter();
FileStream fstream = new FileStream("c:\\Person_SOAP_XML.xml", FileMode.OpenOrCreate);
formatter.Serialize(fstream, person);
fstream.Close();
}
catch (Exception exp)
{
rt = exp.StackTrace;
}
return rt;
}

[WebMethod]
public string DeSerialize()
{
string rt = "DeSerialize OK!";
try
{
SoapFormatter formatter = new SoapFormatter();
FileStream fstream = new FileStream("c:\\Person_SOAP_XML.xml", FileMode.Open);
Person person = (Person)formatter.Deserialize(fstream);
fstream.Close();
rt += "\n\tName = " + person.Name + "\n\tAge = "+person.Age;
}
catch (Exception exp)
{
rt = exp.StackTrace;
}
return rt;
}
}

[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://www.rookiesoft.com/webservices/")]
[Serializable()]
public class Person
{
public string Name;
public int Age;

public Person()
{
this.Name = "Noname";
this.Age = 0;
}
public Person(string name, int age)
{
this.Name = name;
this.Age = age;
}
}
}
idiotzeng 2003-01-07
  • 打赏
  • 举报
回复
我这边.NET环境出了点问题,不能运行WEB SERVICES,无法帮你调试
你把你的错误信息描述详细一点
chenbinghui 2003-01-04
  • 打赏
  • 举报
回复
这里出错,
~~~~~
错误是什么?
idiotzeng 2002-12-30
  • 打赏
  • 举报
回复
你Web Services的代码怎么写的?
idiotzeng 2002-12-30
  • 打赏
  • 举报
回复
1、将http://schemas.microsoft.com/clr/assem/tt中的tt改为Web Services中相应的程序集名称试试
2、将http://schemas.microsoft.com/clr/assem/tt中的assem改为nsassem试试
3、在Web Services中先序列化,再反序列化,看生成的文件和你上面贴出来的文件有什么不同
Kyle-soft 2002-12-29
  • 打赏
  • 举报
回复
我已经通过XmlSerializer实现, 但如果哪位解决了SoapFormatter这个问题, 600分我还是照给不误.!

12,162

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 Web Services
社区管理员
  • Web Services社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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