如何获得WCF代理来处理子集合

本文关键字:处理 子集合 代理 何获得 WCF | 更新日期: 2023-09-27 17:57:29

我今天正在学习,我做了我的第一个非常简单的WCF服务。我创建了几个非常简单的类,如下所示(这被简化了一点)。。。

//contact class  
public class Contact
{
    public int Id { get; set; }

    private ObservableCollection<Phone> _contactPhones = new ObservableCollection<Phone>();
    public ObservableCollection<Phone> ContactPhones
    {
        get { return _contactPhones; }
        set { _contactPhones = value; }
    }
    public string FirstName { get; set; }
    public string LastName { get; set; }
}
// phone class  
public class Phone
{
    public string PhoneNumber { get; set; }
    public PhoneTypes PhoneType { get; set; }
}

我有一个模拟存储库类,它返回联系人类的集合

class ContactRepositoryMock : IContactRepository
{
    private readonly ObservableCollection<Contact> _contactList;
    public ContactRepositoryMock()
    {
        _contactList = new ObservableCollection<Contact>();
        Contact contact = this.Create();
        contact.Id = 1;
        contact.FirstName = "Seth";
        contact.LastName = "Spearman";
        contact.ContactPhones.Add(new Phone(){PhoneNumber = "864-555-1111",PhoneType = PhoneTypes.Mobile});
        contact.ContactPhones.Add(new Phone(){PhoneNumber = "864-555-2222",PhoneType = PhoneTypes.Home});
        this.Save(contact);
    }
    public ObservableCollection<Contact> GetContacts()
    {
        return _contactList;
    }
}

Save和Create方法未显示,但Save添加到_contactList集合,Create创建联系人的新实例(请注意,contact ctor正在使用急切加载来初始化phone _contactPhones集合)

最后,我围绕ContactRepositoryMock.GetContacts方法创建了一个WCF服务包装,如下所示。。。

[ServiceContract(Namespace = "")]
[SilverlightFaultBehavior]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class ContactsService
{
    private ContactRepositoryMock _contactRepository = new ContactRepositoryMock();
    [OperationContract]
    public ObservableCollection<Contact> GetContacts()
    {
        return _contactRepository.GetContacts();
    }
}

另一个项目是Silverlight项目(这就是我今天要学习的内容)

在那个项目中,我向WCF类添加了一个Web引用,Visual Studio像往常一样添加了代理类。

我在项目中添加了一个MainPageViewModel,如下所示:

public class MainPageViewModel : ViewModelBase
{
    public MainPageViewModel()
    {
        if (!IsDesignTime)
        {
            //GetContacts();   //not shown               
        }
        else
        {
            var contactList = new ObservableCollection<Contact>();
            var contact = new Contact {Id = 1, FirstName = "Seth", LastName = "Spearman"};
            contact.ContactPhones.Add(new Phone() { PhoneNumber = "864-555-1111", PhoneType = PhoneTypes.Mobile });
            contact.ContactPhones.Add(new Phone() { PhoneNumber = "864-555-2222", PhoneType = PhoneTypes.Home }); 
            contactList.Add(contact);
            Contacts= contactList;
        }
    }
    private ObservableCollection<Contact> _contacts;
    public ObservableCollection<Contact> Contacts
    {
        get { return _contacts; }
        set
        {
            if (value!=_contacts)
            {
                _contacts = value;
                OnPropertyChanged("Contacts");
            }
        }
    }
}

与以下XAML

<UserControl x:Class="MVVMDemo.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    xmlns:viewModels="clr-namespace:MVVMDemo.ViewModels"
    d:DesignHeight="300" d:DesignWidth="400">
    <UserControl.Resources>
        <viewModels:MainPageViewModel x:Key="ViewModels" />
    </UserControl.Resources>
    <Grid x:Name="LayoutRoot" 
          DataContext="{Binding Source={StaticResource ViewModels}}"
          Background="White">
    </Grid>
</UserControl>

这是一个错误的大量背景,最终可能是一个简单的解释。

XAML行<viewModels:MainPageViewModel x:Key="ViewModels" />下面有一个歪歪扭扭的字,并返回错误"Cannot create and instance of MainPageViewModel"。

我甚至知道那个错误的原因。如果我禁用了联系人。ContactPhones.添加MainPageViewModel ctor中的…行,然后错误就会消失。

最后,我甚至知道为什么错误会消失。这是因为创建WCF代理类的引用文件没有初始化ContactPhones集合。

换句话说,在代理中生成的类Reference.cs中,如果我更改了读取。。。

private System.Collections.ObjectModel.ObservableCollection<MVVMDemo.WSProxy.Phone> ContactPhonesField;

private System.Collections.ObjectModel.ObservableCollection<MVVMDemo.WSProxy.Phone> ContactPhonesField = new ObservableCollection<Phone>();

那么我可以重新启用联系人。联系电话。添加…行,错误就会消失。该项目编译并运行。

所以。。。只是简单地问。。。如何让Visual Studio生成一个代理类来初始化我的集合。或者我做这件事的方式有缺陷吗?我错过了什么

很抱歉提供了这么多细节,但我不确定呼叫链中哪里可能出现故障。在这个问题得到回答后,我还将利用所有这些细节再问几个问题。

Seth

如何获得WCF代理来处理子集合

WCF根本不调用任何构造函数。两种选择:

  • 添加反序列化回调(MSDN)
  • 在属性中处理

IMO第二个更容易:

ObservableCollection<Phone> _contactPhones;
[DataMember]
public ObservableCollection<Phone> ContactPhones
{
    get { return _contactPhones ?? (
        contactPhones = new ObservableCollection<Phone>());
}

在MainPageViewModel:的构造函数中添加电话号码之前,请尝试添加此行

contact.ContactPhones=新的ObservableCollection();

我不会花太多精力让WCF生成子集合。如果你必须重新生成代理服务,你的工作将被彻底删除。如果您将WCF类视为模型,我会创建模型并将其转换为ViewModels。这里的好处是,ViewModel实现可以包含映射代码,以便将Model显式转换为ViewModel。ViewModel类不必在每次生成Reference.cs时重写或更新。