无法发送任何非通用类型的内容

Ich*_*ann 5 c# wcf visual-studio-2010

我有基于本教程的应用程序

我用来从服务获取用户列表的方法:

public class PBMBService : IService
{
    public ServiceResponse UserList()
    {
        try
        {
            sql.Open();
            List<User> result = new List<User>();

            //filling list from database

            return new ServiceResponse(SRFlag.OK, result);
        }
        catch (Exception ex)
        {
            return new ServiceResponse(SRFlag.EXCEPTION, ex);
        }


    }

//other methods
}
Run Code Online (Sandbox Code Playgroud)

服务主要功能:

class Program
{
    static void Main(string[] args)
    {
        Uri baseAddress = new Uri("http://localhost:8000/PBMB");

        ServiceHost selfHost = new ServiceHost(typeof(PBMBService), baseAddress);

        try
        {
            selfHost.AddServiceEndpoint(
                typeof(IService),
                new WSHttpBinding(),
                "PBMBService");

            ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
            smb.HttpGetEnabled = true;
            selfHost.Description.Behaviors.Add(smb);

            selfHost.Open();
            Console.WriteLine("Serwis gotowy.");
            Console.WriteLine("Naci?nij <ENTER> aby zamkn?? serwis.");
            Console.WriteLine();
            Console.ReadLine();


            selfHost.Close();
        }
        catch (CommunicationException ce)
        {
            Console.WriteLine("Nast?pi? wyj?tek: {0}", ce.Message);
            selfHost.Abort();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

其他类在
Classes.cs中

namespace PBMB
{
public enum SRFlag { OK, EXCEPTION };

[DataContract]
public class ServiceResponse
{
    private SRFlag _flag;
    private Object _content;

    public ServiceResponse(SRFlag srf, Object c)
    {
        _flag = srf;
        _content = c;
    }

    [DataMember]
    public SRFlag Flag
    {
        set { _flag = value; }
        get { return _flag; }
    }

    [DataMember]
    public Object Content
    {
        set { _content = value; }
        get { return _content; }
    }
}

[DataContract]
public class User
{
    [DataMember]
    public string Login { get; set; }
    [DataMember]
    public string FirstName { get; set; }
    [DataMember]
    public string MiddleName { get; set; }
    [DataMember]
    public string LastName { get; set; }
    [DataMember]
    public string Email { get; set; }
}
}
Run Code Online (Sandbox Code Playgroud)

我的问题是:为什么我不能发送任何非通用类型的东西?我需要发送List<User>,User[]但我甚至无法发送int[2](发送intstring可能).

当我尝试将List从服务发送到客户端时,服务可以工作,但我在客户端得到异常:

An error occurred while receiving the HTTP response to http://localhost:8000/PBMB/PBMBService.  
This could be due to the service endpoint binding not using the HTTP protocol.  
This could also be due to an HTTP request context being aborted by the server  
(possibly due to the service shutting down). See server logs for more details.  
Run Code Online (Sandbox Code Playgroud)

emp*_*mpi 3

我想发生这种情况是因为 User 类被声明为 DataContract 并且数据序列化器能够序列化和反序列化它。

但是,将对象声明为返回响应的一部分是一个非常糟糕的主意。您应该始终指定返回的类型。返回对象违反消息传递原则。服务客户端应该能够从 wsdl 获取所需的所有信息,如果将部分响应定义为对象(什么样的对象?.net 特定对象?等)基本上是不可能的。消息传递原理与面向对象完全不同原则。

另外,如果您想向客户端返回异常,请检查FaultException

更新:

怎么解决呢?

  1. 更改您的设计 - 不要指望您可以发送任何对象。对于 SOA 和消息传递来说,这是一个错误的假设。
  2. 如果您想发送基本类型(例如 int、string)的对象,只需在响应中声明您将返回public string Contentpublic int Number- 就像您所做的那样,但显式声明类型(不要使用对象)。如果您想返回自定义类,即 User,请像您所做的那样声明它(DataContract、DataMember 等 - 但不是必需的),然后编写public User Content. 它将发挥作用,客户将知道在服务响应中期望什么。