【问题标题】:How can I expose a .Net 2.0 Webservice to a Silverlight client?如何向 Silverlight 客户端公开 .Net 2.0 Web 服务?
【发布时间】:2009-08-20 15:05:58
【问题描述】:

我有一个简单的 .Net 2.0 SOAP Web 服务。我想从托管在同一服务器上但端口不同的 Silverlight 应用程序访问它。我知道要使其工作,我需要提供 clientaccesspolicy.xmlcrossdomain.xml 策略文件(该服务在 http://example:8085/RemoteObject.rem?wsdl 可用,因此策略文件必须存在于 http://example:8085/crossdomain.xml)。我应该在self-serve the policy file like the WCF example does 的以下简单 Web 服务中添加什么?

Web 服务正在 Mono 上运行,尽管这不会改变任何东西 - 只是不涉及 IIS。

using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Http;

namespace ConsoleApplication1
{
    class RemoteObject : MarshalByRefObject
    {
        static void Main()
        {
            var channel = new HttpChannel(8085);
            ChannelServices.RegisterChannel(channel, false);

            RemotingConfiguration.RegisterWellKnownServiceType(
                typeof(RemoteObject), "RemoteObject.rem",
                WellKnownObjectMode.Singleton);

            Console.WriteLine("Press ENTER to exit the server.");
            Console.ReadLine();
        }

        public DateTime Now()
        {
            return DateTime.Now;
        }
    }
}

编辑:由于所有无法使用的答案,让我重复一遍:我需要使用 .Net 2.0,而不是 3.0 或 3.5 来执行此操作。 WCF 不可用

【问题讨论】:

  • 你有没有试过在windows机器上运行你的webservice ..?这行得通吗??
  • 是的,确实如此,只是 Silverlight 安全限制阻止了我想到的场景。

标签: c# silverlight web-services .net-2.0 mono


【解决方案1】:

我对 MONO 中的部署网络了解不多。如果您没有为您的问题找到更好的方法,我会建议另一种方法。

您可以使用

从托管的 silverlight 代码中调用 javascript 方法,而不是直接从 silverlight 应用程序调用 web 服务。
string sJson = HtmlPage.Window.Invoke("JSMethod", new string[] { strInParam }) as string;

并向您的服务器发出 AJAX 请求(来自 JS 方法),并将在内部调用部署在 MONO 中的 Web 服务(来自服务器)并返回 JSON 格式的结果。

我已经在我的项目中实施了这种方法并且它工作正常..

只是一个选择..

【讨论】:

    【解决方案2】:

    好的,我可以说答案不是一个简单的步骤。请查看 Cassini 开源 Web 服务器,您必须在您的应用程序中实现一个小型 Web 服务器并在您的自定义 Web 服务器中运行您的自定义服务。

    打开此 silverlight 的最佳方法是,创建一个 IFrame 并让它从您的自定义端口本身从您的自定义 Web 服务器加载 html/aspx。因此,您不需要任何跨域策略问题。

    【讨论】:

      【解决方案3】:

      EDIT2我的同事找到了一个可用的解决方案:来自 Microsoft 的 Web Service Enhancements。它确实需要 IIS,并且随着 WCF 的引入而被弃用,但在普通的 .Net Framework 2.0 中运行良好,并且应该可以使用 Mono XSP 进行部署。

      编辑下面的解决方案毫无意义,因为 .Net 2.0 使用 SOAP 1.1 rpc/编码模型公开 Web 服务,而 Silverlight 需要 SOAP 1.2 文档/文字。因此,虽然解决方法适用于问题中指出的问题,但仍然无法使用 Web 服务。

      我成功地完成了这项工作,而没有采取极端的黑客手段。我的解决方案的关键是在请求处理队列中插入一个额外的IServerChannelSink。所以,我改变了

      var channel = new HttpChannel(8085);
      

      在正常管道之前注册我的自定义IServerChannelSink

      var provider = ChainProviders(
        new PolicyServerSinkProvider(),
        new SdlChannelSinkProvider(),
        new SoapServerFormatterSinkProvider(),
        new BinaryServerFormatterSinkProvider());
      var channel = new HttpChannel(new Hashtable(1) {{"port", 8085}}, null, provider);
      

      我使用辅助方法将接收器提供者链接在一起:

      private static IServerChannelSinkProvider ChainProviders(
        params IServerChannelSinkProvider[] providers)
      {
        for (int i = 1; i < providers.Length; i++)
          providers[i-1].Next = providers[i];
        return providers[0];
      }
      

      PolicyServerSinkProvider 只是创建一个PolicyServerSink

      internal class PolicyServerSinkProvider : IServerChannelSinkProvider
      {
        public void GetChannelData(IChannelDataStore channelData){}
      
        public IServerChannelSink CreateSink(IChannelReceiver channel)
        {
          IServerChannelSink nextSink = null;
          if (Next != null)
            nextSink = Next.CreateSink(channel);
          return new PolicyServerSink(channel, nextSink);
        }
      
        public IServerChannelSinkProvider Next { get; set; }
      }
      

      PolicyServerSink 将所有消息委托到链中,除非它收到对 crossdomain.xml 的请求 - 然后它将所需的 xml 写入响应流。

      internal class PolicyServerSink : IServerChannelSink
      {
        public PolicyServerSink(
          IChannelReceiver receiver, IServerChannelSink nextSink)
        {
          NextChannelSink = nextSink;
        }
      
        public IDictionary Properties { get; private set; }
      
        public ServerProcessing ProcessMessage(
          IServerChannelSinkStack sinkStack, IMessage requestMsg,
          ITransportHeaders requestHeaders, Stream requestStream,
          out IMessage responseMsg, out ITransportHeaders responseHeaders,
          out Stream responseStream)
        {
          if (requestMsg != null || ! ShouldIntercept(requestHeaders))
            return NextChannelSink.ProcessMessage(
              sinkStack, requestMsg, requestHeaders, requestStream,
              out responseMsg, out responseHeaders, out responseStream);
      
          responseHeaders = new TransportHeaders();
          responseHeaders["Content-Type"] = "text/xml";
          responseStream = new MemoryStream(Encoding.UTF8.GetBytes(
            @"<?xml version=""1.0""?><!DOCTYPE cross-domain-policy SYSTEM "
            + @"""http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd"">"
            + @"<cross-domain-policy><allow-access-from domain=""*"" />"
            + @"</cross-domain-policy>")) {Position = 0};
          responseMsg = null;
          return ServerProcessing.Complete;
        }
      
        private static bool ShouldIntercept(ITransportHeaders headers)
        {
          return ((string) headers["__RequestUri"]).Equals(
            "/crossdomain.xml", StringComparison.InvariantCultureIgnoreCase);
        }
      
        public void AsyncProcessResponse(IServerResponseChannelSinkStack sinkStack,
          object state, IMessage msg, ITransportHeaders headers, Stream stream)
        {
        }
      
        public Stream GetResponseStream(IServerResponseChannelSinkStack sinkStack,
          object state, IMessage msg, ITransportHeaders headers)
        {
          throw new NotSupportedException();
        }
      
        public IServerChannelSink NextChannelSink { get; private set; }
      }
      

      这也可用于与 Web 服务一起提供其他文件。我目前正在使用这种方法来托管我的 Silverlight 应用程序(Web 服务的使用者),而无需单独的 http 服务器。

      【讨论】:

      • .NET 2.0 也可以做文档/文字。
      【解决方案4】:

      【讨论】:

      • WCF => 至少 .Net 3.0。我知道这对 WCF 来说是微不足道的,我只是没有使用它的奢侈。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-03
      • 2017-12-16
      • 1970-01-01
      • 2021-06-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多