[问题]
创建了要部署在服务器计算机和客户端计算机上的共享库,如何在客户端服务器与库提供的类之间进行通信?
通过webservices传输信息似乎不起作用,因为Web服务返回的序列化对象是一个不转换为共享库的Web服务类。
我是否错误地使用了网络服务?还有更好的方法吗?
[示例]
MyLibrary.cs和SubLibrary.cs位于客户端应用程序使用的共享程序集中。
MyLibrary.cs
public class MyLibrary
{
private SubLibrary sublib = new SubLibrary();
public class MyLibrary()
{
}
public string GetValue()
{
return sublib.GetValue();
}
}
SubLibrary.cs
public class SubLibrary
{
private string str = "Hello World";
public SubLibrary()
{
}
public string GetValue()
{
return str;
}
}
WebService.asmx.cs
[WebMethod]
public MyLibrary GetInfo()
{
return new MyLibrary();
}
客户端应用
private void GetInfo_Click(object sender, System.EventArgs e)
{
WS.WebService services = new WS.WebService();
MyLibrary info = services.GetInfo(); // This of course doesn't convert.
MessageBox.Show(info.GetValue());
}
答案 0 :(得分:5)
简而言之,这是1.1的痛苦(部分也是2.0)。仅真正的程序集共享(或类型共享)开始成为WCF(.NET 3.0)中的一项功能。 1.1中生成的代理永远不会直接与“实际”类兼容;您可以在多个服务(“sharetypes”?)之间共享相同的代理,但不能与独立的源文件IIRC共享。
由于它是C#1.2,你既没有部分类也没有扩展方法来欺骗它们。
选项(我可以看到):
XmlSerializer
(代码少,但速度不快)答案 1 :(得分:1)
使用Web服务,您通过线路发送的每个对象的类型必须是可序列化的。您可以通过实现IXmlSerializable接口使SubLibrary可序列化。
public class SubLibrary : IXmlSerializable
{
private string str = "Hello World";
public SubLibrary()
{
}
public string GetValue()
{
return str;
}
public XmlSchema GetSchema()
{
return null;
}
public void ReadXml(XmlReader reader)
{
//...
}
public void WriteXml(XmlWriter writer)
{
//...
}
}
但有一点需要注意:由于您通过WS传递了MyLibrary和SubLibrary,因此需要确保它们都是可序列化的。此外,由于您正在传递MyLibrary并且包含 SubLibrary的实例,因此您必须在序列化期间维护MyLibrary和SubLibrary之间的关系,这将是一个问题。除非你有其他理由想要在我不了解的MyLibrary中封装SubLibrary的实例,否则我将摆脱那个中间层,让你的Web服务只返回SubLibrary的一个实例。所以你只需要:
[WebMethod]
public SubLibrary GetInfo()
{
return new Sublibrary();
}
在客户端应用中:
private void GetInfo_Click(object sender, System.EventArgs e)
{
WS.WebService services = new WS.WebService();
SubLibrary info = services.GetInfo(); // This of course doesn't convert.
MessageBox.Show(info.GetValue());
}
通过Web服务传递复杂对象的好方法是:将一个实例的所有数据成员序列化为XML,通过网络发送,然后将其反序列化为另一端的实际数据。不要将它视为通过网络发送实际类(使用非数据成员)。
答案 2 :(得分:0)
通常,您需要为服务添加Web引用。这将创建一个客户端代理,其中包含客户端可用于调用Web服务而不是公共库的类。
在你的情况下,它可能看起来像:
WS.WebService services = new WS.WebService();
// Use client side proxy in same namespace as generated web reference
WS.MyLibrary info = services.GetInfo();
我似乎记得在生成的代理类中替换我的公共库(作为测试),一切似乎都有效。但不建议这样做,也不保证能够正常工作。
它可能只是您的示例,但您的MyLibrary类没有要返回的数据。原因是XmlSerializer(由运行时用于在XML和CLR对象之间进行转换)仅序列化对象的公共属性和字段。 MyLibrary和SubLibrary不公开任何属性或公共字段,因此不会序列化数据。有关详细信息,请参阅XML and SOAP Serialization