C# 正在寻找序列化方法或常量的变通方法

C# 正在寻找序列化方法或常量的变通方法,c#,wcf,serialization,C#,Wcf,Serialization,显然,我的教育让我失望,因为我没有意识到C#中的方法不能序列化。(很高兴知道。) 我正在尝试创建一个WCF服务,它返回我创建的一个简单类。问题是这个简单的类包含我想要公开的方法,而我的服务的调用者将无权访问它们(假设它们没有包含类声明的.dll) 我设置了一个WCF服务(我们称之为MyService)来返回我的简单类的一个实例。令我沮丧的是,我的班级只恢复了一部分 public void CallService() { using (var client = new MyService.

显然,我的教育让我失望,因为我没有意识到C#中的方法不能序列化。(很高兴知道。)

我正在尝试创建一个WCF服务,它返回我创建的一个简单类。问题是这个简单的类包含我想要公开的方法,而我的服务的调用者将无权访问它们(假设它们没有包含类声明的.dll)

我设置了一个WCF服务(我们称之为MyService)来返回我的简单类的一个实例。令我沮丧的是,我的班级只恢复了一部分

public void CallService()
{
    using (var client = new MyService.Serviceclient())
    {
        Simple result = client.GetSimple();
        string message = result.Message; // this works.
        string hidden = result.Hidden;  // this doesn't.
        string fail = result.GetHidden(); // Underpants remains elusive.
    }
}

是否有任何类型的变通方法可以让调用我的服务的任何人都可以访问我的类上的属性或方法?如何处理在仅存在于服务中的类中设置的常量或其他方法?

通常您会创建三个不同的项目

 1. Service project
 2. Client project 
 3. Data project
数据项目只包含数据类,没有应用程序代码。这些数据类中的方法和常量应该独立于服务/客户机项目。 数据项目作为引用包含在服务和客户机项目中,以便对同一个二进制文件进行序列化和反序列化,并且您可以保留常量/方法/等等


这里的缺点是,您的所有客户端都必须是.NET应用程序,或者您必须为希望支持的每个平台提供不同的数据库。

据我所知,WCF服务中只能返回原语或具有公共属性的类,这些类上有get方法。WCF允许您在客户端和服务器之间指定一个契约,该契约在理论上与传输无关(即,您可以将HTTP端点替换为netTcp端点,并且服务将以相同的方式从契约级别运行)

然后要回答的问题是,在这个服务调用中,您试图传回哪些数据。如果它是一个名为simple的对象,带有消息的数据点并隐藏,那么我建议创建一个名为simple的数据类,该类将这些值作为属性:

[DataContract]
public class Simple
{
    [DataMember]
    public string Hidden { get; set; }

    [DataMember]
    public string Message { get; set; }
}
当客户机接收到响应返回消息并隐藏时,将使用您在服务器端设置的值填充

该属性只能用于属性和字段。这意味着WCF响应只能序列化这些类型

如果您真的只想在WCF协定中使用常量,可以将其转换为字段,并在其上放置DataMember属性:

public class Simple
{
    [DataMember]
    public string Message { get; set; }

    [DataMember]
    public const string Hidden = "Underpants";
}
要做到这一点,该字段必须是可访问的(公共)。

将添加到属性中。为此,必须同时定义
get
set

[DataMember]
public string Hidden
{
    get { return _Hidden; }
    set { }
}

从技术上讲,您可以这样做

public class thingToSerialize{
    public Func<ArgType1,ArgType2...,ReturnType> myFunction{get;set;}
}
公共类thingToSerialize{
公共函数myFunction{get;set;}
}
然后为其分配一个lambda,该lambda接受参数并返回返回类型
在序列化之前

理想情况下,您可以创建一个契约,也就是一个简单的POCO类,它只是公共属性,并将其序列化。使用其他方法从您拥有的任何内部业务逻辑/数据填充POCO。您的用户调用您的WCF来执行您的逻辑,而不是让逻辑返回到他们的系统上执行。在服务器上执行您的逻辑通常会产生数据(并且只有数据),这些数据会被发送回客户端,以处理它所需要的任何方式。这两点都非常有效,谢谢@cgotberg,你让我的思想朝着正确的方向发展。非常感谢!奇怪的在我的例子中,只要我添加了空集{},即使没有指定DataMember属性,它也可以访问。我不知道为什么会这样,但谢谢你!我认为如果不使用
DataContractAttribute
标记该类,
DataMemberAttribute
是不必要的。你应该用
DataContractAttribute
来标记它,以表明它是可序列化的,但是正如你所看到的,它是双向工作的。我的主要问题是我没有花时间创建一个只包含数据而不包含逻辑的合同类。这种方法比我所走的方向更有意义。非常感谢。当谈到面向对象编程时,这是一种正确的本能。应用程序(在本例中为客户端和服务器)之间的边界与本文所述的情况不同:
public class thingToSerialize{
    public Func<ArgType1,ArgType2...,ReturnType> myFunction{get;set;}
}