首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

Silverlight 2 + WCF 打造服務導向豐富客戶端:跨域策略、非同步通訊、資料繫結模式與 INotifyPropertyChanged 實戰

     編輯:關於.NET

前言

Silverlight 2 (Beta 2) 引入了強大的 XAML 資料繫結、控制項範本與 WCF 非同步通訊能力,使得構建企業級豐富互聯網應用 (RIA) 成為可能。本文基於 MSDN 專欄實例,完整演示從 WCF 服務建置、跨域策略配置、Silverlight 客戶端開發、ListBox 資料模板繫結、非同步服務呼叫、ThreeWay/TwoWay/OneWay 繫結模式選擇,到 INotifyPropertyChanged 變更通知機制的端到端實作。

一、 範例應用架構概覽

  • 後端:Northwind 資料庫 + WCF 服務 (basicHttpBinding) + ClientAccessPolicy.xml 跨域授權
  • 前端:Silverlight 2 控制項 (ListBox, TextBox, CheckBox, Button) + 服務代理 + 非同步事件模式
  • 實體:Product, Category 標註 [DataContract]/[DataMember] 透過 WCF 序列化傳輸

二、 WCF 服務關鍵配置

2.1 繫結必須為 basicHttpBinding

Silverlight 2 僅支援 basicHttpBinding (SOAP 1.1 / HTTP)。wsHttpBinding 會導致通訊失敗。

<endpoint address="" binding="basicHttpBinding" contract="MyService.INWServiceGateway" />

或使用 VS 模板 "Silverlight-enabled WCF Service" 自動配置。

2.2 跨域策略檔案:ClientAccessPolicy.xml

Silverlight 執行於客戶端瀏覽器沙箱,呼叫不同網域/埠/協定的服務需授權。瀏覽器依序尋找:

  1. ClientAccessPolicy.xml (Silverlight 專用,優先)
  2. crossdomain.xml (Flash 相容)

檔案必須置於 **Web 站點根目錄** (非應用程式虛擬目錄)。

<?xml version="1.0" encoding="utf-8"?>
<access-policy>
  <cross-domain-access>
    <policy>
      <allow-from http-request-headers="*">
        <domain uri="*"/> <!-- 允許所有網域,生產環境請限制具體網域 -->
      </allow-from>
      <grant-to>
        <resource path="/" include-subpaths="true"/>
      </grant-to>
    </policy>
  </cross-domain-access>
</access-policy>

除錯提示:使用 Fiddler / Web Development Helper 檢查 HTTP 流量;確認策略檔在網站根目錄 (如 https://localhost:port/ClientAccessPolicy.xml 可下載)。

三、 Silverlight 客戶端開發

3.1 加入服務參考

專案右鍵 → "Add Service Reference" → 輸入服務 URL → 命名空間。產生代理類 NWServiceGatewayClient 與實體類 (Product, Category)。

3.2 ListBox + DataTemplate 豐富呈現

<ListBox x:Name="lbProducts" ItemsSource="{Binding}">
  <ListBox.ItemTemplate>
    <DataTemplate>
      <StackPanel Orientation="Horizontal">
        <StackPanel Orientation="Vertical">
          <TextBlock Text="{Binding ProductName, Mode=OneWay}" FontSize="14"/>
          <TextBlock Text="{Binding CategoryName, Mode=OneWay}"/>
        </StackPanel>
        <Grid>
          <TextBlock Text="Price:"/>
          <TextBlock Text="{Binding UnitPrice, Mode=OneWay, Converter={StaticResource priceConverter}}"/>
        </Grid>
      </StackPanel>
    </DataTemplate>
  </ListBox.ItemTemplate>
</ListBox>

程式碼後置設定 lbProducts.DataContext = productList; 即完成繫結。

3.3 非同步服務呼叫模式 (APM)

private void FindProductList()
{
    this.Cursor = Cursors.Wait;
    var proxy = new NWServiceGatewayClient();
    proxy.FindProductListCompleted += FindProductListCompleted;
    proxy.FindProductListAsync(); // 非同步啟動
}

private void FindProductListCompleted(object sender, FindProductListCompletedEventArgs e)
{
    var productList = e.Result; // ObservableCollection
    lbProducts.DataContext = productList;
    if (lbProducts.Items.Count > 0) lbProducts.SelectedIndex = 0;
    this.Cursor = Cursors.Arrow;
}

四、 資料繫結模式深度解析

模式初始化時更新目標來源變更更新目標目標變更更新來源適用場景
OneTime✓✗✗靜態唯讀資料 (版權聲明、固定標籤)
OneWay✓✓ (需 INotifyPropertyChanged)✗動態唯讀資料 (清單顯示、詳情檢視)
TwoWay✓✓ (需 INotifyPropertyChanged)✓ (失去焦點時)可編輯表單欄位 (TextBox, CheckBox, ComboBox)

實例應用

  • ProductName (ListBox TextBlock) → OneWay
  • CategoryName (Detail TextBlock) → OneWay
  • UnitsInStock (Editable TextBox) → TwoWay
  • UnitPrice (Editable TextBox) → TwoWay + Converter 格式化

五、 INotifyPropertyChanged:變更通知核心

來源物件必須實作 INotifyPropertyChanged,在屬性 Setter 中引發 PropertyChanged 事件,繫結引擎才能感知變更並更新目標。

5.1 基底類別實作

[DataContract]
public abstract class EntityBase : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

5.2 實體類別繼承與屬性實作

[DataContract]
public class Product : EntityBase
{
    private decimal _unitPrice;
    [DataMember]
    public decimal UnitPrice
    {
        get { return _unitPrice; }
        set
        {
            if (_unitPrice != value)
            {
                _unitPrice = value;
                OnPropertyChanged("UnitPrice"); // 觸發通知
            }
        }
    }
    // 其他屬性同理...
}

5.3 連鎖更新效果

  1. 使用者在 TextBox 編輯 UnitPrice (TwoWay)
  2. TextBox 失去焦點 → 更新來源 Product.UnitPrice
  3. Setter 引發 PropertyChanged("UnitPrice")
  4. ListBox 中同樣繫結 UnitPrice (OneWay) 的 TextBlock 自動更新顯示新價格

六、 取消/重新整理功能實作

private void btnCancel_Click(object sender, RoutedEventArgs e)
{
    // 重新從服務取得最新資料,覆寫 DataContext
    proxy.FindProductListAsync(); // 完成事件中重設 DataContext
}

若繫結模式為 OneTime,重設 DataContext 也不會更新 UI;OneWay/TwoWay 會自動重繫結更新。

結語

Silverlight 2 + WCF 為 RIA 開發奠定了堅實基礎:basicHttpBinding 互通性、ClientAccessPolicy.xml 安全跨域、非同步 APM 模式、聲明式 XAML 繫結、三種繫結模式精準控制、INotifyPropertyChanged 響應式 UI。掌握這些核心機制,您將能構建出既美觀又健壯的企業級 Silverlight 應用程式。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved