【问题标题】:Pass Objects between Client and Server C# WCF在客户端和服务器 C# WCF 之间传递对象
【发布时间】:2013-11-25 14:03:12
【问题描述】:

我正在为医疗数据实施分布式处理系统。我有多个客户端和服务器。客户端有数据,他们向服务器发送请求进行处理。

我必须将两个值传输到服务器并返回一个列表。服务器实现定义为:

[ServiceContract]
public interface ServerInterface
{
    [OperationContract]
    List<Triangle> ServerFunction(Grid g, double isolevel);
} 

public class ServerImpl : ServerInterface
 {
       public List<Triangle> ServerFunction(Grid g, double isolevel)
       {/*Implementation*/}
 }

网格类定义为:

[Serializable]
 public class Grid
 {
    public Point3D[] p = new Point3D[8];
    public Int32[] val = new Int32[8];
 }

Triangle 类为

  [Serializable]
  public class Triangle
  {
     public Point3D[] p = new Point3D[3];
  }

我创建了客户端和服务器端实现,isolevel 值可以正常传递,但网格没有正确传递。

服务器使用此代码创建 WCF 服务:

        Uri baseAddress = new Uri("http://localhost:6525/ServerObject");

        using (ServiceHost host = new ServiceHost(typeof(ServerImpl), baseAddress))
        {
            ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
            smb.HttpGetEnabled = true;
            smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;
            host.Description.Behaviors.Add(smb);

            host.Open();
            Console.ReadKey();
         }

调用服务器获取结果的代码部分是:

var myBinding = new BasicHttpBinding();
var myEndPoint = new EndpointAddress("http://localhost:6525/ServerObject");
var myChannelFactory=new ChannelFactory<ServerInterface>(myBinding,myEndPoint);
ServerInterface si=null;
si = myChannelFactory.CreateChannel();


List<Triangle> triList=si.ServerFunction(Grid g,double isoValue);

它从不返回三角形列表(总是返回 null)。

此代码在转换为分布式之前经过测试并且工作正常。

我正在使用 WCF,我尝试将 Grid 和三角形转换为字符串值并传递它们,它可以工作,但速度很慢。该算法本身需要大量时间,因此不需要额外的处理时间。有什么想法吗?

【问题讨论】:

  • 你试过用 DataContract 代替 Serializable 吗?
  • 我试过了,但到达服务器的 Grid 对象为空。
  • 愚蠢的问题,但是当您调用服务时,您是否确认您的网格对象不是null
  • 是的。它在通过之前创建并检查。当我尝试从服务器访问 gridcell 对象时,它说对象引用未设置为对象的实例。

标签: c# wcf serialization distributed-computing


【解决方案1】:

您应该通过将[DataContract] 属性添加到要序列化的类来使用DataContractSerializer。然后将[DataMember] 属性添加到每个类的成员。所以你会有这样的东西:

[DataContract]
public class Grid
{
   [DataMember]
   public Point3D[] p = new Point3D[8];

   [DataMember]
   public Int32[] val = new Int32[8];
}

更多信息可以在微软的网站here找到。

【讨论】:

  • 我这样做了,但网格对象没有被传递。当我尝试从服务器端访问网格对象时,它说对象引用未设置为对象实例。我不明白为什么。
  • 除了将上面提到的属性添加到您的类之外,您实际上还必须对对象进行序列化和反序列化才能传递它们。以下是 Microsoft 网站上关于如何使用 DataContractSerializer Person p = new Person(); DataContractSerializer dcs = new DataContractSerializer(typeof(Person)); XmlDictionaryWriter xdw = XmlDictionaryWriter.CreateTextWriter(someStream,Encoding.UTF8 ); dcs.WriteObject(xdw, p); 序列化对象的摘录 在我提到的 link 上提供了说明
【解决方案2】:

我拿了你的代码并在下面实现了服务器代码:

        var v = new List<Triangle>();
        var t1 = new Triangle();
        t1.p = new Point3D[3];
        t1.p[0] = new Point3D(1,2,3);
        t1.p[1] = new Point3D(2,2,3);
        t1.p[2] = new Point3D(3,2,3);

        v.Add(t1);
        return v;

客户很好地收到了三角坐标。您是否验证过您的服务器实际上正确地填充了阵列?下面是我的简单客户端代码。为了创建代理,我刚刚启动了服务器,并从客户端项目中添加了对

的服务引用
http://localhost:6525/ServerObject?wsdl 

-

        var c = new ServerInterfaceClient();
        var v=c.ServerFunction(new Grid(), 34.3);
        foreach (var triangle in v)
        {
            Console.WriteLine("X:"+ triangle.p[0]._x);
            Console.WriteLine("y:"+ triangle.p[0]._y);
            Console.WriteLine("z:"+ triangle.p[0]._z);
        }

抱歉,我无法提供更多帮助,但我会在服务器端和客户端添加一些登录信息,以尝试查看对象丢失的位置。您的 wcf 设置应该没有任何问题。

【讨论】:

  • 这里的问题似乎是 Grid 对象没有到达服务器。使用网格值计算三角形位置。如何确认我的对象正在到达服务器?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多