5

我正在尝试让服务器应用程序使用 WCF 公开一些状态信息。特别是我在使用带有 RESTful“API”的 WCF 服务之后。当谈到从我想作为另一种客户端类型的 silverlight 应用程序/页面使用 REST api 时,我遇到了一些障碍......

到目前为止,我已经成功定义了一个状态界面:

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 代码时,我的选择是:

  • 使用 WebClient 编写丑陋的代码,这最终意味着每当我对我的 API 进行更改时,我都必须更新两组代码
  • 对 WebService 使用 SOAP/WS 并不断更新 Visual Studio 中的服务引用

有没有办法在 SilverLight 中使用 WebChannelFactory 保持“干净”的实现?或许是 SilverLight 的公共领域/开源 WebChannelFactory?

对此的任何帮助将不胜感激!

4

5 回答 5

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 服务做了同样的事情,而且效果很好。

于 2008-11-24T16:31:59.070 回答
1

我几乎不想建议它,但是您对重新实现 WebChannelFactory<T> 类感到满意吗?

粗略浏览一下 Silverlight API,您似乎不会从 Microsoft 开箱即用地获得太多帮助。您需要为它重新实现一个通道类和一个工厂。

也许另一种创建通道并将自己与特定于平台的代码隔离的方法是创建它的自定义实现?具体来说,我的意思是,您创建了另一个工厂类,并且工厂类在可用时调用 WebChannelFactory,或者为您进行设置。

抱歉,我没有更深入的建议。:)

于 2008-11-12T07:39:53.180 回答
1

您缺少 Spring.Rest : http ://springframework.net/index.html#spring-rest-1.0.0-released

于 2011-04-21T12:51:46.590 回答
1

到目前为止,我已经找到了一些 WebChannelFactory 的替代方案,用于在 Silverlight 中使用 REST 服务。他们都在论坛和博客上看到了赞誉,但我自己还没有尝试过。我相信这三个都使用泛型轻松地将请求响应反序列化为 CLR 对象。

我倾向于 RestSharp,因为它的示例在我看来既简单又可扩展。

于 2011-04-20T09:29:39.857 回答
0

I recently ran into the same problem and decided to create a class that has a simplified REST client interface for Silverlight, more or less like WebChannelFactory. Has synchronous-like behavior also.

http://regular-language.blogspot.com/2011/06/wcf-webhttp-rest-client-for-silverlight.html

于 2011-06-11T22:59:27.713 回答