在 WCF 中使用 DataContract 传递对象

jam*_*dev 1 c# wcf struct object

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

我有一个 WCF 服务(通过 namedpipe)和一个客户端。我需要传递一个对象(最好是该对象的引用)作为我的 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)

}
Run Code Online (Sandbox Code Playgroud)

这是服务合同:

[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);
}
Run Code Online (Sandbox Code Playgroud)

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

proxy.getArray(ref myCount, ref myIntArray, new D(source))
Run Code Online (Sandbox Code Playgroud)

我也试过这个:

D d = new D(source)
proxy.getArray(ref myCount, ref myIntArray, d)
Run Code Online (Sandbox Code Playgroud)

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

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

我在这里没有想法了....

Joc*_*cke 5

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

您的服务运营:

[OperationContract]
int getArray(ref int count, ref int[] array, D d);
Run Code Online (Sandbox Code Playgroud)

将返回一个 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();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)