2011-05-20 42 views
2

我今天正在學習,我做了第一個非常簡單的WCF服務。我創建了幾個非常簡單的類,如下所示(這是簡化了一下)......你如何得到一個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; 
    } 

} 

另存和創建方法不顯示,但保存添加到_contactList集合和創建創建一個新的聯繫人實例(注意聯繫人正在使用急切加載初始化手機_contactPhones集合)

最後,我創建了一個WCF服務包裝聯繫人RepositoryMock.GetContacts方法如下...

[ServiceContract(Namespace = "")] 
[SilverlightFaultBehavior] 
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)] 
public class ContactsService 
{ 
    private ContactRepositoryMock _contactRepository = new ContactRepositoryMock(); 

    [OperationContract] 
    public ObservableCollection<Contact> GetContacts() 
    { 
     return _contactRepository.GetContacts(); 
    } 
} 

另一個項目是Silverlight項目(這是真的是我今天s'posed要學習。)

在該項目中,我添加一個Web引用我的WCF類和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" />在它下面有一個波形,並返回錯誤「無法創建MainPageViewModel和實例」。

我甚至知道該錯誤的原因。如果我禁用了MainPageViewModel中的contact.ContactPhones.Add ...行,那麼錯誤就會消失。

最後,我甚至知道爲什麼錯誤消失。這是因爲創建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>(); 

然後我就可以重新啓用contact.ContactPhones.Add ...行並且錯誤消失。該項目編譯並運行。

所以只需要問......我如何讓Visual Studio生成一個代理類來啓動我的集合。或者我在做這件事的方式有缺陷嗎?我錯過了什麼?

對不起所有的細節,但我不確定在調用鏈中可能出現故障。在這個問題得到解答之後,我也將使用所有這些細節問幾個更多的問題。

賽斯

回答

0

嘗試加入這一行,你在構造函數中添加前的電話號碼MainPageViewModel:

contact.ContactPhones =新的ObservableCollection();

4

WCF不會調用任何構造函數(完全)。有兩種選擇:

  • 在物業

IMO第二添加反序列化回調MSDN

  • 手柄更容易:

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

    +1。正如Marc所提到的,WCF或更準確地說,DataContract反序列化或任何反序列化只是創建填充對象,它不會調用構造函數。 – CodingWithSpike 2011-05-23 11:18:55

    +0

    @ rally25rs - 請注意,XmlSerializer,JavaScriptSerializer等確實調用了ctors – 2011-05-23 17:45:02

    +0

    真的嗎?呵呵,我從來沒有注意到XmlSerializer調用構造函數。怎麼樣的屬性設置方法?爲什麼XmlSerializer和DataContractSerializer之間的設計差異? – CodingWithSpike 2011-05-23 20:32:07

    0

    我不會去通過大量的努力讓WCF生成一個子集合。如果您必須重新生成代理服務,您的工作將被徹底清除。如果您將您的WCF類作爲模型對待,我會創建模型並將其轉換爲ViewModels。這樣做的好處是您的ViewModel實現可以包含映射代碼以將模型顯式轉換爲ViewModel。每次生成Reference.cs時,ViewModel類都不必重寫或更新。

    相關問題