WCF/Silverlight注意事項

ByteBlocks的博客文章中總結了開發WCF/Silverlight的注意事項,這樣的經驗之談字字千鈞,可以讓後來的開發者少走許多彎路。

綁定的選擇

毫無疑問,我們應該選擇BasicHttpBinding,這也是Silverlight僅僅支持的一種綁定。

WCF異常的處理

Silverlight無法獲取WCF異常(例如:FaultException)。如果WCF服務拋出WCF異常,在客戶端應用程序只能夠獲得 HTTP 404錯誤。無疑,這會干擾調用者對異常的捕捉,同時也無法獲知真正的異常信息。一種好的做法是在服務方法中定義一個out參數,在該參數中包含HTTP Status以及異常信息。可以定義一個返回信息的數據契約,例如:

[DataContract]
public class CallResult
{
    public CallResult()
    {
        StatusCode = 0;
        StatusMessage = "OK";
    }
    [DataMember]
    public int StatusCode
    {get; set;}
    [DataMember]
    public string StatusMessage
    {get; set;}
    [DataMember]
    public string ExceptionDetails
    {get; set;}
}

編寫服務方法時,可以採用如下方式:

public double Convert(string from, string to, out CallResult status)
{
    status = new CallResult();
    if (string.IsNullOrEmpty(from) ||
        string.IsNullOrEmpty(to))
    {
        status.StatusCode = 2;
        status.StatusMessage = "Invalid or empty curreny symbols specified";
        return 0;
    }
    try
    {
        string config = ConfigurationManager.AppSettings["htmlparserconfig"];
        var converter = new CurrencyConverter(config);
        return converter.Convert(from, to);
    }
    catch (Exception ex)
    {
        status.StatusCode = 9;
        status.StatusMessage = "Failed to get currency conversion rate";
        status.ExceptionDetails = ex.Message;
        //TODO: Log this message.
    }
    return 0;
}

WCF服務的部署

在將WCF服務部署在Web服務器上時,最好在配置文件中爲WCF服務添加一個基地址。如果未來需要修改WCF服務的部署地址,僅僅需要修改配置文件的基地址即可,其餘位置不需要做任何修改。

<host>
  <baseAddresses>
    <add baseAddress="http://www.myhostserver.com/MyWCFServices/"/>
  </baseAddresses>
</host>

此外,至關重要的一點是要讓服務跨域邊界可用。Silverlight 在默認情況下只允許源站點通信。若要允許 Silverlight 控件訪問其他域上的服務,該服務必須明確選擇允許跨域訪問。通過選擇,服務聲明它公開的操作可以由 Silverlight 控件安全地調用,而不會對該服務存儲的數據造成具有潛在危害的結果。Silverlight 2.0 支持兩種不同的機制供服務選擇跨域訪問:
(1)在承載服務的域的根目錄中放置一個 clientaccesspolicy.xml 文件,以配置服務允許跨域訪問。
(2)在承載服務的域的根目錄中放置一個有效的 crossdomain.xml 文件。該文件必須將整個域標記爲 public。

例如,創建如下的clientaccesspolicy.xml文件:

<?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>

如果只允許從其他域中的一個進行訪問(例如 http://agiledon.com),clientaccesspolicy.xml 應當包含以下配置:

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

然後再將該文件保存到託管該服務的域的根目錄中。例如,如果該服務在 http://agiledon.com 上承載,則文件必須位於 http://agiledon.com/clientaccesspolicy.xml。

如果進行如上的配置,在Silverlight跨域訪問時,就會出現一個安全錯誤。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章