2008-11-10 21 views
5

我想讓服務器應用程序使用WCF公開一些狀態信息。 特別是我使用RESTful「API」使用WCF服務之後。 當我想要從Silverlight 應用/頁面中消費REST API時,我想要作爲一種附加類型的客戶端...什麼是製作Silverlight和Regular .NET REST客戶端的最便攜的方式

到目前爲止,我已成功地定義一個狀態界面:

public static class StatusUriTemplates 
{ 
    public const string Status = "/current-status"; 
    public const string StatusJson = "/current-status/json"; 
    public const string StatusXml = "/current-status/xml"; 
} 
[ServiceContract] 
public interface IStatusService 
{ 
    [OperationContract] 
    [WebGet(ResponseFormat = WebMessageFormat.Json, UriTemplate = StatusUriTemplates.StatusJson)] 
    StatusResultSet GetProgressAsJson(); 

    [OperationContract] 
    [WebGet(ResponseFormat = WebMessageFormat.Xml, UriTemplate = StatusUriTemplates.StatusXml)] 
    StatusResultSet GetProgressAsXml(); 

    [OperationContract] 
    [WebGet(UriTemplate = StatusUriTemplates.Status)] 
    StatusResultSet GetProgress(); 
} 

在服務器中執行它:

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)] 
    public class ServerStatusService : IStatusService 
    { 
    public StatusResultSet GetProgressAsJson() 
    { return GetProgress(); } 

    public StatusResultSet GetProgressAsXml() 
    { return GetProgress(); } 

    public StatusResultSet GetProgress() 
    { 
     return StatusResultSet.Empty; 
    } 
    } 

在運行時從我的代碼將它暴露

我甚至已經成功使用的東西沿着該線從.NET控制檯/ winfoems/WPF應用程序消耗的服務:

var cf = new WebChannelFactory<IStatusService>(new Uri("http://localhost:8000/server/status")); 
    var ss = cf.CreateChannel(); 
    Console.WriteLine(ss.GetProgress().TimeStamp); 

的「牆」我打的是,有SliverLight沒有WebChannelFactory。

期間。

這意味着,當談到Silverlight的代碼,我的選擇是:使用Web客戶端, 這最終意味着我將有 更新兩套代碼每當 我有一個變化

  • 寫醜陋的代碼我的API
  • 使用SOAP/WS爲WebService,並保持 從 更新服務引用的Visual Studio

有沒有辦法在SilverLight中使用WebChannelFactory保持「乾淨」的實現? 也許是SilverLight的公共領域/開源WebChannelFactory?

任何幫助,將不勝感激!

+0

這方面的進展如何? – andrecarlucci 2010-12-20 13:06:59

回答

1

我幾乎不想暗示它,但你會覺得舒服reimplementing the WebChannelFactory<T> class

從粗略瀏覽Silverlight API看起來,您不會從Microsoft開箱即得任何幫助。你需要爲它重新實現一個頻道類和一個工廠。

也許另一種創建通道並將自己與平臺特定代碼隔離的方法是創建一個自定義的實現?具體來說,我的意思是,您創建了另一個工廠類,並且工廠類在可用時調用WebChannelFactory,或者經歷爲您設置的環節。

對不起,我沒有更深入的建議。 :)

+0

我想我會按照你的提議重新實施工廠課程。 我想我會用林福這樣的東西去做所有的繁重工作。 我只需要看看LinFu是否在Silverlight – damageboy 2008-11-17 09:02:31

+0

@damageboy上有什麼進展? – andrecarlucci 2010-12-20 13:07:14

1

如果這是一個簡單的Xml REST服務,爲什麼不使用Silverlight中的WebClient來使用Linq to XML捕獲XML?我知道你說過它的混亂,但這一切取決於你如何看待它。如果您隨時更改服務界面,則必須在多個位置更新您的代碼。就是那樣子。

所以要做到這一點,您需要從WebClient以異步方式捕獲數據,然後使用LINQ將其解析爲XML。

時間雅表在他的網站一個很好的例子:http://timheuer.com/blog/archive/2008/03/14/calling-web-services-with-silverlight-2.aspx

從本質上講,它看起來像這樣:

WebClient rest = new WebClient(); 
rest.DownloadStringCompleted += new DownloadStringCompletedEventHandler(rest_DownloadStringCompleted); 
rest.DownloadStringAsync(new Uri("http://example.org/current-status/xml")); 

然後在你的「rest_DownloadStringCompleted」你解析字符串作爲XML。像這樣:

string data = e.Result; 
string url = string.Empty; 

XDocument doc = XDocument.Parse(e.Result); 
var myResults = from results in doc.Descendants("myXmlElement") ... blah blah blah 

我已經用WCF和Silverlight的自制REST服務做了同樣的事情,它工作得很好。

1

到目前爲止,我已經發現WebChannelFactory的一些替代方法來消費Silverlight中的REST服務。他們都在論壇和博客中看到過讚美,但我還沒有嘗試過任何一個。我相信所有三種使用泛型都可以輕鬆地將請求響應反序列化爲CLR對象。

我傾向於RestSharp移植,因爲它看起來的例子既簡單,可擴展的給我。

相關問題