2009年5月6日 星期三

在 Silverlight 中使用 WCF 的心得

最近在開始才有機會使用 Silverlight. 這裡將遇到的心得寫下來,以便大家參考(當然也包括自己)
  1. Silverlight 2.0 只能使用 basicHttpBinding,尚未無法使用 wsHttpBinging。
  2. 在 Silverlight 2.0  中當作 WCF Client 呼叫 WCF Service 時,需注意到有許多特性不能使用。否則會發生則似下面的錯誤訊息。

Message: Unhandled Error in Silverlight 2 Application Unrecognized attribute 'allowCookies' in service reference configuration. Note that attribute names are case-sensitive. Note also that only a subset of the Windows Communication Foundation configuration functionality is available in Silverlight.  

其實 Visual Studio 2008 在開發時已經有提醒了,只是我沒注意到。看 config file 的 editor 畫面,有出現 blue underline 的提醒。
image

    3.  我是使用於 MOSS 的環境下,開發時會使用 http://moss/ 來存取 MOSS,而 WCF Client 在呼叫時,預設會寫成 http://moss.domain.com/ 這樣的存取方式。

<client>
 <endpoint name="BasicHttpBinding_IMyService" contract="MossServices.IMyService" binding="basicHttpBinding" address="http://epmoss.domain.com/wcf/MyService.svc" bindingconfiguration="BasicHttpBinding_IMyService" />
</client>
這樣一來,SilverLight 會以為是跨 domain 來存取 wcf,且認為是不安全的。於是又開始找 clientaccesspolicy.xml (see 讓服務可跨網域界限使用)
因此,必須手動地改成相同的 domain. 如下
<client>
  <endpoint name="BasicHttpBinding_IMyService" contract="MossServices.IMyService" binding="basicHttpBinding" address="http://epmoss/wcf/MyService.svc" bindingconfiguration="BasicHttpBinding_IMyService" />
</client>

   4.  WCF 預設無法讀取 asp.net 環境的 Context。如果需要讀取 Context,則必須做以下的改變。(參考 這裡)

第一個,是在 class 上增加[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)] 的attribute

[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
  public class MyService : IMyService
  {
    public string GetCurrentSiteName()
    {
      
      SPContext context = SPContext.Current;
      var q = (from SPList i in context.Web.Lists
               select i.Description).ToArray();
      return string.Join(",", q);
    }
  }

第二,是在 Web.config 上增加下列設定 (字體放大加粗的部份)。此用意在讓wcf 環境可與 asp.net 相容外,也要讓 client side 的資訊能傳到 wcf service 來。

<system.serviceModel>
    <bindings>
      <basicHttpBinding>
        <binding name="myBasicBinding">
          <security mode="TransportCredentialOnly">
            <transport clientCredentialType="Ntlm"/>
          </security>
        </binding>
      </basicHttpBinding>
    </bindings>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
    <services>
      <service behaviorConfiguration="MossWcfServiceLibrary.MyServiceBehavior"
        name="MossWcfServiceLibrary.MyService">
        <endpoint address="" binding="basicHttpBinding" bindingConfiguration="myBasicBinding"
          contract="MossWcfServiceLibrary.IMyService">
          <identity>
            <dns value="localhost" />
          </identity>
        </endpoint>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="MossWcfServiceLibrary.MyServiceBehavior">
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="true" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>

沒有留言:

Share with Facebook