【问题标题】:Passing an object using DataContract in WCF在 WCF 中使用 DataContract 传递对象
【发布时间】:2013-02-19 11:29:09
【问题描述】:

[编辑] 我现在已经使用构造函数和调用客户端代码以及 OnDeserializing() 和 OnDeserialized() 方法编辑了 D。

我有一个 WCF 服务(通过命名管道)和一个客户端。我需要传递一个对象(最好是该对象的引用)作为我的 OperationContract 的参数。

[DataContract]
public class D
{
    [DataMember] 
    public int Id;

    [DataMember] 
    public string StrId;

    //...


    public D(int id, string strid)
    {
        Id = id;
        StrId = strid;
        //...
    }

    [OnDeserialized]
    void OnDeserialized(StreamingContext strmCtx)
    {
    } // breakpoint here (1)

    [OnDeserializing]
    void OnDeserializing(StreamingContext strmCtx)
    {
    } // breakpoint here (2)

}

这是服务合同:

[ServiceContract]
public interface ICalc
{
    [OperationContract]
    int Calculate(string date, int count);

    // d is input of this method, and count and array are outputs.
    [OperationContract]
    int getArray(ref int count, ref int[] array, D d);
}

这是我调用 getArray 的客户端代码:

proxy.getArray(ref myCount, ref myIntArray, new D(source))

我也试过这个:

D d = new D(source)
proxy.getArray(ref myCount, ref myIntArray, d)

显然这不会改变任何东西,在这两种情况下,当我在服务代码(getArray 方法的代码)中收到 d 时,它的所有字段都是空的。这是为什么?有什么我遗漏的吗?

我知道(使用启用跟踪并查看传输层的消息)字段的传输层值正在在线上正确传输。我还向对象添加了 OnDeserialized() 和 OnDeserializing() 方法,以便我可以在断点 (1) 和 (2) 处放置一个断点,所有字段都为空?! 实际上根本没有调用对象设置器!

我的想法已经用完了......

【问题讨论】:

  • 你确定你真正的D 实现就像显示的那样吗?可能是ctor中的字段初始化有问题吗?
  • 谢谢,是的,我有一个构造函数,我已经编辑了我的帖子以反映这一点。现在有什么明显的问题吗?
  • 我会尝试添加默认的ctorprotected,因为您可能不希望它是public)。也许这会导致反序列化问题。
  • 没有任何差异。我仍然得到空值。
  • 您能否显示调用getArray 的代码,以及您作为参数传递的内容?我想看看你在哪里初始化D d

标签: c# wcf object struct


【解决方案1】:

WCF 是面向数据的(序列化的 xml),而不是面向对象的。那是行不通的!

您的服务运营:

[OperationContract]
int getArray(ref int count, ref int[] array, D d);

将返回 int 的数据值。如果您想获取 int 值和数组值,我建议您为它创建一个 [DataContract] ,包含这两个值。这样,它们将作为数据传递给客户端。

使用 (ref int[]) 调用服务操作不会产生影响。

更新一些代码: 抱歉,我无法发现您的错误。这是您可以比较的小示例(有效)。如果您仍然无法修复错误,我建议您发布完整的代码和配置。

using System.Runtime.Serialization;
using System.ServiceModel;

namespace WcfService2
{
    [ServiceContract]
    public interface IService1
    {
        [OperationContract]
        string GetData(InputData value);
    }

    [DataContract]
    public class InputData
    {
        [DataMember]
        public int[] Array { get; set; }
        [DataMember]
        public D SomeStuff { get; set; }
    }

    [DataContract]
    public class D
    {
        [DataMember]
        public int Id { get; set; }
    }
}

using System;

namespace WcfService2
{
    public class Service1 : IService1
    {
        public string GetData(InputData data)
        {
            if (data.Array == null || data.SomeStuff == null)
                throw new NullReferenceException();
            return "OK!";
        }
    }
}

using ConsoleApplication9.ServiceReference;
using System;

namespace ConsoleApplication9
{
    class Program
    {
        static void Main(string[] args)
        {
            var proxy = new Service1Client();
            var request = new InputData
                {
                    Array = new int[] {1, 2, 3},
                    SomeStuff = new D {Id = 42}
                };
            Console.WriteLine(proxy.GetData(request));
            Console.ReadKey();
        }
    }
}

【讨论】:

  • 您是说 WCF 无法在客户端序列化我的对象并发送它,而在服务器上创建对象的新实例并通过反序列化传递的对象来分配字段值?
  • 你说什么行不通?你当然可以传递对象,WCF 只会以不同的方式处理它。
  • @sam 不是正在传递的对象,而是数据,它们在客户端和服务器端被序列化。这就是我的观点。
  • @Jocke 我关心的它的d,接收端d的所有字段都是空的。
  • @jambodev 所以它们在服务端总是为空,而不是在客户端?
【解决方案2】:

你有默认构造函数吗,如果没有,WCF 将无法理解它。

另外 - ref int[] array - 数组无论如何都会作为引用类型传递。

【讨论】:

  • 我确实有一个公共的默认构造函数,但是服务端的字段值仍然为空,这让我发疯。如何启用跟踪,以便我可以看到客户端正在序列化的内容,我假设我可以使用 SvcTraceViewer.exe 进行跟踪?
【解决方案3】:

感谢您的所有帮助和回复。 最后,我解决了这个问题。一旦我将 D 放在它自己的程序集中并从服务和客户端都引用它,它就开始工作了。

【讨论】:

    【解决方案4】:

    在将一些参数分组到 DataContract 类后,我遇到了同样的问题。

    我实际上有两个客户端,一个使用与服务器共享的接口程序集工作得很好。 使用 ServiceContract 和 DataContract 的代码副本的另一个客户端无法正常工作,并且我的 DataContract 参数服务器端的所有成员都是 0 或 null,如上所述。

    问题似乎是由于我将 DataContract 放入客户端的命名空间。 我负责将我的 DataContract 放在与来自主客户端程序集的名称空间相同的名称空间中,这解决了我的问题。事实上,除了回调类之外,我将所有合约类都放在同一个命名空间中。所以也许这不仅仅是 DataContract 的问题。虽然在不使用 DataContract 时工作正常,但我想这是唯一导致问题的原因。

    希望它有意义。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多