【问题标题】:WebService: How to return an array of a complex type?WebService:如何返回复杂类型的数组?
【发布时间】:2010-08-31 16:29:24
【问题描述】:

真的有2个问题,我不确定我这样做是否正确......

我想为我创建的实体对象发回某种类型的数组。我不确定如何将其标记为发送(需要哪些属性或其他),也不确定如何将其发送回(IList、List、Collection、ICollection)。

理想情况下,我希望能够发回 ObservableCollection,但如果想要使用该服务的客户端不在 .NET 中,这是否可行?

[ServiceContract(Namespace = "http://www.tempuri.com/MyService",
                 ConfigurationName = "IMyService")]
public interface IMyServie
{
    [OperationContract(Action = "http://www.tempuri.com/MyService/GetUsers",
                       ReplyAction = "*")]
    [XmlSerializerFormat(SupportFaults = true)]
    GetUsersResponse GetUsers(GetUsersRequest request);
}

[MessageContract(IsWrapped = false)]
public sealed class GetUsersRequest
{
    public GetUsersRequest() { }
    public GetUsersRequest(Int32 record = -1)
    {
        Record = record;
    }

    [MessageBodyMember(Namespace = "", Order = 0)]
    public Int32 Record { get; private set; }

}

[MessageContract(IsWrapped = false)]
//[ServiceKnownType(??)]
public sealed class GetUsersResponse
{
    public GetUsersResponse() { }
    public GetUsersResponse(PersonEntity[] entities)
    {
        Entities = entities;
    }

    [MessageBodyMember(Namespace = "", Order = 1)]
    //[XmlElement(DataType = "??")]
    public PersonEntity[] Entities { get; private set; }
    //Should this have been some other type of array-type (Collection, List, etc?)
}

//Does this need any attributes besides Serializable?
[Serializable()]
public PersonEntity : AbstractEntity
{
    public PersonEntity() { }
    public PersonEntity(Int32 id = 0, String fname = "", String lname = "")
    {
        ID        = id;
        FirstName = fname;
        LastName  = lname;
    }

    public String FirstName { get; set; }
    public String LastName { get; set; }

    //Functionality (Clone, Clear, Default, Equals, etc) Removed...
}

[Serializable()]
public abstract class AbstractEntity : IEntity
{
    public Int32 ID { get; set; }

    //Abstracts or Implements some functionality...
}

public interface IEntity
{
    //Defines functionality requirements
}

【问题讨论】:

  • 我建议将 [Serializable] 替换为 [DataContract]。

标签: c# wcf collections observablecollection complextype


【解决方案1】:

DataContract 是您正在寻找的。更多详情请查看link

在 Observable 集合方面,不知道为什么发送数组对您来说会有所不同。您能否详细说明一下以帮助我们理解这一点。

【讨论】:

  • 是否必须在父抽象类和接口上标记这个DataContract?
  • 拥有派生类Personentity的属性就足够了。因为这是唯一通过通道交换的类型
【解决方案2】:

在通过网络传递对象时,您必须考虑数据而不是行为。因此,就这一点而言,List 或 IEnumerable 或 T[] 不会有所不同,我的偏好是所有语言都支持的数组。服务器不应该知道或对客户端(WPF、Windows 窗体等)做出任何不必要的假设,并且您传递的只是数据集合,因此规定最少的是最好的:T[](T 数组)。

正如 myermian 所说,通过网络发送的 ObservableCollection 不会在客户端上作为 ObservableCollection 工作。

此外,您正在使用 MessageContract,而没有使用 Body/Header 的任何好处。所以你必须使用 DataContract。

【讨论】:

    【解决方案3】:

    最可互操作的方法是返回一个复杂类型的数组,无论你决定是什么。我个人的偏好是使用专用的 DTO 对象进行网络传输,而不是直接通过服务公开内部实体。

    关于ObservableCollection,我建议您将数组包装在ObservableCollection 客户端中,而不是尝试返回ObservableCollection

    请记住,ObservableCollection 不会将更改传输回服务;您将不得不手动执行这些操作。

    【讨论】:

    • 我只是想看看是否可以跳过 Array-To-ObservableCollection 的步骤,因为客户端将是 WPF。
    • @myermian:你可能可以——毕竟OC 是可序列化的——但我不会。首先,你不会得到任何好处;例如,如果服务有新数据,则服务返回的OC 不会更新,并且对其的更新不会传播回服务。其次,它会不必要地破坏您可能获得的任何互操作性。这对你来说可能是也可能不是问题,但对我来说永远是个问题——我喜欢保持我的选择。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-01-27
    • 2021-04-13
    • 1970-01-01
    • 2014-06-27
    • 2013-05-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多