2010年9月17日金曜日

ClientAccessPolicy.xmlの書式

WCFはクロスドメイン間での実行に制限をかけられるので、
不特定ドメインからの実行は許可すべきではない。

以下は、ドメインhoge.localとVisualStudioでのデバッグ用にlocalhostのみ許可する設定。

<?xml version="1.0" encoding="utf-8"?>
<access-policy>
  <cross-domain-access>
    <policy>
      <allow-from http-request-headers="*">
        <domain uri="http://hoge.local" />
        <domain uri="http://localhost:1335" />
      </allow-from>
      <grant-to>
        <resource path="/" include-subpaths="true" />
      </grant-to>
    </policy>
  </cross-domain-access>
</access-policy>

2010年9月16日木曜日

TimeoutExceptionの回避

処理に時間のかかるWCFサービスを呼び出すと、TimeoutExceptionが返ってくる。

これはデフォルトでWCFサービスが1分間処理を返してこないと、タイムアウトするようになっているから。

これを回避するにはクライアント側の設定ファイルServiceReferences.ClientConfigのsendTimeoutの値を変更。以下の例では10分に設定。

<binding name="CustomBinding_Service" sendTimeout="00:10:00">
  <binarymessageencoding />
  <httptransport maxReceivedMessageSize="10485760" maxBufferSize="10485760" />
</binding>

DataContractの初期化

WCFでDataContractとして定義したクラスのメンバを初期化したい、ってことはよくあるけど、以下のようにコンストラクタを追加してみたってどうにもなりません。

[DataContract]
    public class Shop
    {
        [DataMember]
        public short ID { get; set; }
        [DataMember]
        public string Name { get; set; }
        [DataMember]
        public string Address { get; set; }
        [DataMember]
        public string Phone { get; set; }
        [DataMember]
        public string Fax { get; set; }
        [DataMember]
        public List<Employee> Employee { get; set; }

        public Shop()
        {
            Employee = new List<Employee>();
        }
    }

WCFでシリアライズされている型をいじるには、クライアント側でパーシャルクラスを定義すればよいだけ。

同じShopクラスならこんな具合。(WCFのコレクション型をObservableCollectionにシリアライズした場合)

public partial class Shop : IEditableObject
    {
        public Shop
        {
            Employee = new ObservableCollection<Employee>();
        }
    }

パーシャルクラスを使えば、IEditableObjectとかの実装もできるようになる。