我正在尝试使用WCF来获取服务器应用程序以显示某些状态信息。 特别是我在使用RESTful“API”的WCF服务之后。 当谈到从Silverlight消费REST api时,我有点像墙 我希望将app / page作为另一种类型的客户端...
到目前为止,我已经成功定义了一个状态界面:
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;
}
}
在运行时从我的代码中公开它:
var service = new ServerStatusService();
var binding = new WebHttpBinding();
var behavior = new WebHttpBehavior();
var host = new WebServiceHost(service, new Uri("http://localhost:8000/server"));
host.AddServiceEndpoint(typeof(IStatusService), binding, "status");
host.Open();
我甚至成功地使用.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代码时,我的选择是:
有没有办法在SilverLight中使用WebChannelFactory保持“干净”的实现? 也许SilverLight的公共域/开源WebChannelFactory?
非常感谢任何帮助!
答案 0 :(得分:1)
我几乎不想提出建议,但你会对reimplementing the WebChannelFactory<T> class感到满意吗?
从粗略的一瞥到Silverlight API,看起来你不会得到微软开箱即用的帮助。你需要为它重新实现一个通道类和一个工厂。
创建频道并将自己与特定于平台的代码隔离开来的另一种方法是创建它的自定义实现吗?具体来说,我的意思是,你创建了另一个工厂类,并且工厂类在可用时调用WebChannelFactory,或者为你设置它的环节。
对不起,我没有更深入的建议。 :)
答案 1 :(得分:1)
如果这是一个简单的Xml REST服务,为什么不使用Silverlight中的WebClient来使用Linq to XML捕获XML?我知道你说它凌乱,但这一切都取决于你如何看待它。如果您在任何时候更改服务界面,则必须在多个位置更新代码。就是那样子。
为此,您需要从WebClient以异步方式捕获数据,然后使用LINQ to XML解析它。
Time Heuer在他的网站上有一个很好的例子: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服务做了同样的事情,并且效果很好。
答案 2 :(得分:1)
到目前为止,我已经找到了一些WebChannelFactory的替代品,用于在Silverlight中使用REST服务。他们都在论坛和博客中看到了赞誉,但我还没有尝试过任何一个。我相信所有这三个都使用泛型来轻松地将请求响应反序列化为CLR对象。
我倾向于RestSharp,因为它的例子看起来既简单又可扩展。
答案 3 :(得分:1)
你缺少Spring.Rest: http://springframework.net/index.html#spring-rest-1.0.0-released
答案 4 :(得分:0)
我最近遇到了同样的问题,并决定创建一个具有简化的Silverlight REST客户端界面的类,或多或少像WebChannelFactory。也有类似同步的行为。
http://regular-language.blogspot.com/2011/06/wcf-webhttp-rest-client-for-silverlight.html