【问题标题】:Cross-platform RESTful WCF method, passing and returning byte array跨平台RESTful WCF方法,传递和返回字节数组
【发布时间】:2013-01-04 04:47:30
【问题描述】:

理论上如此简单,但我从来都不是 WCF 配置方面的专家。我想要做的是:我有一个匹配这个签名的 WCF 方法:

[OperationContract]
[WebInvoke(Method = "POST")]
Stream PostPackets(Stream rawPackets);

我真正关心的是从 Android/iPhone/Blackberry/任何其他类型的设备获取一个字节数组到我的 wcf 服务,处理该数组,然后发回一个不同的字节数组。就我而言,它可能看起来像:

[OperationContract]
[WebInvoke(Method = "POST")]
byte[] PostPackets(byte[] rawPackets);

虽然我看到的所有示例似乎都使用了 Stream。

我阅读了许多不同的文章和帖子,但没有直接回答如何在文件传输的上下文之外执行此操作(这不是我的意图)。以下是我面临的问题:

1- 我假设我需要使用 webHttpBinding 来使该服务成为 RESTful。这是正确的吗?如果是这样,你能指出一个示例配置吗?

2 - (这绝对是我在任何地方都找不到的!)我需要确保这不会给设备开发人员带来巨大的痛苦。您能否向我展示使用 RESTful 服务的 Android 和 iPhone 设备的示例以及(非常重要)它们如何向我的服务发送字节数组?

请原谅我的菜鸟... WCF 配置是我每天都不会做的事情之一。一旦我弄清楚了我的配置,我通常会继续前进,直到我的下一个项目(这可能是很长时间)之前都不必碰它。请帮忙!

更新

我的同事建议我们使用 http 处理程序而不是 wcf。我们真的需要这样做吗?
例如:

public void ProcessPackets (HttpContext context) 

更新 2:

我想知道,没有 JSON 有没有办法做到这一点?将数组发布为“text/plain”类型是否有任何缺点/替代方法?

【问题讨论】:

    标签: c# .net web-config cross-platform wcf-rest


    【解决方案1】:

    也许这个简单(且有效的示例)可以提供帮助

    服务器

    void StartServer()
    {
        Task.Factory.StartNew(() =>
        {
            WebServiceHost host = new WebServiceHost(typeof(MyService), new Uri("http://0.0.0.0:80/MyService/"));
            host.Open();
        });
    }
    
    [ServiceContract]
    public class MyService
    {
        [OperationContract]
        [WebInvoke(
            RequestFormat = WebMessageFormat.Json,
            ResponseFormat = WebMessageFormat.Json,
            BodyStyle = WebMessageBodyStyle.WrappedRequest)]
        public byte[] PostPackets(byte[] rawPackets)
        {
            rawPackets[0] = 99;
            return rawPackets;
        }
    }
    

    客户

    <html>
    <script src='jquery-1.8.3.min.js'></script>
    
    <body>
    <script>
             $(document).ready(function () {
                $.ajax({
                    type: "POST",
                    contentType: "application/json",
                    url: "/MyService/PostPackets",
                    data: JSON.stringify({rawPackets:[65,66,67]}), 
                    dataType: "text",
                    success: function (data) {
                        //var div = $("#test").empty();
                        //$("#test").html(data.d);
                        alert('success');
                    },
                    error: function (XMLHttpRequest, textStatus, errorThrown) {
                        alert('error');
                    }
                });
            });
    </script>
    </body>
    </html>
    

    【讨论】:

    • 谢谢,这很好!但我需要确保它在 Android/blackberry/iphone 上也是可行的。
    • 另外,在您上面的示例中,您是否还可以发布 web.config 对于您的 wcf 配置的外观?谢谢
    • 就像我说的,请原谅我出于所有意图和目的,是一个 wcf RESTful 服务菜鸟,但如果你看这里:codeproject.com/Articles/105273/… 我不必设置我的 web.config像第 6 步一样的文件?
    • @saml 要运行上面的代码,您可以创建任何类型的应用程序(即winforms、控制台)。只需在代码中的某处调用StartServer 即可完成。我想不出更简单的方法来创建 RESTful 服务。
    • 哇,如果这适用于我当前的环境(wcf 服务当前作为 Windows 服务托管),那么您节省了我大量时间与配置文件进行斗争以支持多种绑定类型。顺便说一句,这种方法是否支持 ssl?
    【解决方案2】:

    最终解决方案如下。 (确实很简单)

    服务端:

    [ServiceContract]
    public interface IMyService
    {
        [OperationContract]
        [WebInvoke(Method = "POST",
            BodyStyle = WebMessageBodyStyle.Wrapped,
            UriTemplate="TestMethod/")]
        Stream TestMethod(Stream input);
    
    }
    
    public class MyService: IMyService
    {
        Stream IMyService.TestMethod(Stream input)
        {
            byte[] buffer = new byte[10000];
            int bytesRead, totalBytesRead = 0;
            this.currentResponseOffset = 0;
            do
            {
                bytesRead = input.Read(buffer, 0, buffer.Length);
                totalBytesRead += bytesRead;
            } while (bytesRead > 0);
    
            input.Close();
    
            return new MemoryStream(buffer, 0, totalBytesRead);
        }
    }
    

    配置如下:

    <services>
      <service name="MyService" >
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8732/Design_Time_Addresses/MyService/" />
            <add baseAddress="net.tcp://localhost:4504/Design_Time_Addresses/MyService/" />
          </baseAddresses>
        </host>
        <endpoint address="MyTCPService" binding="netTcpBinding" contract="IMyTCPService">
        </endpoint>
    
        <endpoint address="MyHTTPService" binding="webHttpBinding" behaviorConfiguration="web" contract="IMyService"></endpoint>  
    
        <endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange" />
        <endpoint address="mex"  binding="mexHttpBinding" contract="IMetadataExchange"/>
        <!--<endpoint binding="mexHttpsBinding" bindingConfiguration="" contract="IMetadataExchange" />-->
      </service>
    </services>
    <behaviors>
       <endpointBehaviors>
        <behavior name="web">
          <webHttp />
        </behavior>
      </endpointBehaviors>
    </behaviors>
    

    我能够使用 .net 客户端对其进行测试,尽管这篇文章的重点是了解如何使其跨平台。我想我们很快就会看到!感谢@I4V 的帮助,非常感谢。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-06-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-14
      • 2012-07-03
      • 2014-01-01
      相关资源
      最近更新 更多