SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

Silverlight 4で作る新しいRIAアプリケーション

WCF RIA Servicesの仕組み

Silverlight 4で作る新しいRIAアプリケーション(4)

  • X ポスト
  • このエントリーをはてなブックマークに追加

ダウンロード sample.zip (793.6 KB)

その他のサービスメソッドの呼び出し

 WCF RIA Servicesでは、検索、更新、追加、削除といったCRUDを行うメソッド以外にも、ドメインサービスにサービスを登録して、クライアント側から呼び出すことができます。

 リスト6では、「お小遣いService.cs」にコードを追加して、対象月のお小遣い明細の合計金額を算出するサービスを公開しています。

リスト6 対象月のお小遣い明細の合計金額を算出するサービス
[Invoke] 
public int? Get月の合計金額(DateTime 対象月) 
{ 
     var 年 = 対象月.Year; 
     var 月 = 対象月.Month; 
     var 月初 = new DateTime(年, 月, 1); 
     var 月末 = new DateTime(年, 月, DateTime.DaysInMonth(年, 月)); 

     return this.ObjectContext.お小遣い明細 
              .Where(明細 => 月初 <= 明細.日付 && 明細.日付 <= 月末) 
              .Sum(明細 => 明細.金額); 
} 

 コード自体は単にEDMからLINQを使って対象のデータを検索してくるものなので、説明は不要でしょう。ドメインサービスでクライアントに公開したいメソッドは、Invoke属性を指定します。

 Query属性がついたコードとの違いは、WCF RIA Servicesによってデータのトラッキングが行われるかどうかです。リスト7に、このメソッドを呼び出すSilverlight側のコードを示します。

リスト7 対象月のお小遣い明細の合計金額を取得するコード
private void 今月の合計金額_Click(object sender, RoutedEventArgs e) 
{ 
    var context = (お小遣いContext)お小遣い明細DomainDataSource.DomainContext; 
     context.Get月の合計金額( 
         DateTime.Today, 
         result=> MessageBox.Show(string.Format("今月の利用金額:{0}円", result.Value ?? 0)), 
         null); 
} 

 リスト6のコードを記述してコンパイルすると、ドメインコンテキストにサービスの呼び出しコードが追加されるので、先ほど登録したメソッドを呼び出しています。サービス自体は非同期で実行されるため、サービスが終了した際の動作として、メッセージボックスに合計金額を表示させるコードを追加しています。

更新時のエラー処理

 Silverlightでの更新処理は、複数のレコードに対する更新が非同期に行われます。そのため、更新要求が成功したかをSilverlight側で判断するには、更新終了時のイベントハンドラーで、送信した変更セットからエラーの有無を確認する必要があります。

 DomainDataSourceコントロールで更新終了後のイベントは、SubmittedChangesイベントです。リスト8は、更新終了時に更新でのエラーの有無を調べてメッセージを表示する例です。

リスト8 更新終了イベントを補足し、エラーの有無を確認する例
private void お小遣い明細DomainDataSource_SubmittedChanges(object sender, SubmittedChangesEventArgs e) 
{ 
  if (e.HasError)
  { 
      e.MarkErrorAsHandled(); 
      MessageBox.Show("更新エラーが発生しました。"); 
  } 
  else 
  { 
      MessageBox.Show("更新が終了しました。"); 
  } 
} 

 ドメインサービスの更新処理で例外が発生すると、SubmittedChangesEventArgsのHasErrorプロパティにtrueがセットされます。さらに詳しい例外情報を取得したい場合は、EntitiesInErrorプロパティから例外が発生したエンティティの一覧を取得して、原因を調べることができます。

 サーバ側で発生した例外がここで回復(ハンドル)できる場合は、MarkErrorAsHandledメソッドを呼び出し、これ以上例外が伝播しないようにマークする必要があります。例外を補足しない場合は、Application_UnhandledExceptionイベント等で例外を処理します。

TimeStamp列を利用した同時実効性制御

 データベースにSQLServerを利用している場合は、TimeStamp列を利用した楽観的同時実行性制御を行うことができます。この設定は、TimeStamp列に対して、Entity FrameworkのデータモデルでFiexdを設定するだけです(図8)。

図8 楽観的同時実行性制御の設定
図8 楽観的同時実行性制御の設定

 この状態で、複数のブラウザーから同じレコードを更新して保存を行うと、HasErrorプロパティでデータの競合を検知できます。データの競合が発生した場合にSilverlight側で競合を解決する例を、リスト9に示します。

リスト9 競合の解決
if (e.HasError) 
{ 
   // ErrorからDomainOperationExceptionを取り出し、
   var domainOpException = e.Error as DomainOperationException; 
   if (domainOpException != null) 
   { 
       // ステータスがConflicts(競合)のものをチェックする。
       if (domainOpException.Status == OperationErrorStatus.Conflicts) 
       { 
           // エラーが発生したエンティティ一覧から、競合が発生しているレコードを特定し、
           foreach (var err in e.EntitiesInError.Where(err => err.EntityConflict != null)) 
           { 
               // ローカル側の更新を優先する場合はResoleve(解決)を行う 
               err.EntityConflict.Resolve(); 
           } 
       } 
       MessageBox.Show("更新中にデータの競合が発生しました。更新を優先する場合は、再度保存ボタンをクリックしてください。"); 
   } 
   e.MarkErrorAsHandled(); 
}

 サーバ側で競合が発生した場合は、例外のステータスにConflicts(競合)が設定されます。

 データの競合が発生し、ローカル側の更新を優先させたい場合は、EntitiesInErrorプロパティから競合のあったレコードの一覧を取得し、Resolveメソッドを呼び出してデータの競合を解決します。この状態で再度SubmitChangeメソッドを呼び出すと、ローカルのデータを優先してサーバ側を更新できます。

認証が必要なサービスの実装

 Silverlightでユーザ認証や承認機能を実装する場合、ASP.NETの認証や承認機能をそのまま利用できます。WCF RIA Servicesでは、ASP.NETの認証情報を元に、ドメインサービスに登録されたメソッドを、認証の状態や承認されたロールによって許可を与えることができます。

 例えば、お小遣い帳の検索はログイン指定は不要ですが、更新はログインが必要、というような場合です。この場合、認証が必要なドメインサービスのメソッドに、RequiresAuthentication属性を追加します。

 他にも、RequiresRole属性を利用することで、ログイン中のユーザが特定のロールを持っている場合のみ、メソッドの起動を許可するといった制御も可能です。

まとめ

 WCF RIA Servicesはまだ出始めで、かゆいところに手が届かない部分もありますが、今の段階でも十分にビジネスに利用できる状態だと筆者は思います。

 現在のWCF RIA ServicesはSilverlight専用ですが、今後の機能拡張では、WPFやWindowsFormやWebForm、MVCとさまざまな環境で適用できるようになっていくでしょう。これからのn階層アプリケーションの構築では、標準的な位置になってくると予想されます。ぜひこの機会にWCF RIA Servicesに触れてみてください。

参考資料

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
Silverlight 4で作る新しいRIAアプリケーション連載記事一覧

もっと読む

この記事の著者

山田 祥寛(ヤマダ ヨシヒロ)

静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるReact実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

WINGSプロジェクト かるあ (杉山 洋一)(カルア(スギヤマ ヨウイチ))

WINGSプロジェクトについて> 有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。2018年11月時点での登録メンバは55名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂きたい。著書記事多数。 RSS Twitter: @yyamada(公式)、@yyamada/wings(メンバーリスト) Facebook

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/5606 2010/12/28 14:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング