- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我们有一个在 VS2010 中构建并运行的 Web 服务。
一些运营合约如下所示:
[OperationContract]
ITicket Login(string userName, byte[] passwordHash, string softwareVersion);
即他们的展台有复杂的参数和复杂的返回类型,甚至有多个返回。
我们最近启动了一个外包 iPhone 项目,并让他们使用此服务与我们的服务器进行通信。从我从他们那里学到的东西,我明白这不是与 iPhone 通信的好习惯(例如,缺乏使用 WSDL 的好方法)。因此,我开始考虑将服务公开为与 JSON 通信的 REST 服务的可能性。
我添加了一个新端点,使用 webHttpBinding,像这样装饰合约:
[OperationContract]
[WebGet(UriTemplate = "/login?username={userName}&password={password}&softwareVersion={softwareVersion}", ResponseFormat=WebMessageFormat.Json)]
ITicket Login(string userName, string password, string softwareVersion);
此方法现在按预期工作。
然后我尝试像这样装饰另一个方法:
[OperationContract]
[WebGet(UriTemplate = "/GetMetaData?ticket={ticket}",RequestFormat=WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
IMetaData GetMetaData(ITicket ticket);
当我现在尝试访问它时,我收到以下错误:
Server Error in '/Jetas5MobileService' Application. Operation 'GetMetaData' in contract 'IJetas5MobileService2' has a query variable named 'ticket' of type 'Jetas.MobileService.DataContracts.ITicket', but type 'Jetas.MobileService.DataContracts.ITicket' is not convertible by 'QueryStringConverter'. Variables for UriTemplate query values must have types that can be converted by 'QueryStringConverter'.
我已经设法构建了一个 OperationContract,它只接受一个字符串作为参数,然后在后端使用 DataContractJsonSerializer
进行精简解析,但这感觉更像是一个丑陋的 hack。
有什么办法可以更好地解决这个问题吗?我是 WCF 和 REST 的初学者,所以请不要害怕向我指出可能存在的任何初学者教程。我试图搜索它们,但大量的资源使得很难找到好的。
最佳答案
From what I have learnt from them I understood that this is not a good practice for communicating to the iPhone (lack of good ways to consume the WSDL for example).
最大的问题不是缺乏好的“工具”,而是缺乏对 WSDL 是什么以及 Web 服务如何工作的理解。所有这些为开发人员生成服务 stub 的工具导致开发人员不了解底层是什么。它适用于所有魔法都为您完成的基本场景,但一旦开发人员必须跟踪任何问题或使用其他功能扩展“工具”,他们就会遇到大问题(并且通常会导致糟糕的解决方案)。老实说SW开发不是关于基本场景的。
REST 对开发人员来说是一个巨大的挑战,因为它不提供任何“神奇”的工具。 REST 是关于 HTTP 协议(protocol)的正确使用,它充分利用了现有的 HTTP 基础设施。如果不了解 HTTP 协议(protocol)的基础知识,您将无法创建良好的 REST 服务。那是你应该开始的地方。
下面是一些不正确用法的例子:
[OperationContract]
[WebGet(UriTemplate = "/login?username={userName}&password={password}&softwareVersion={softwareVersion}", ResponseFormat=WebMessageFormat.Json)]
ITicket Login(string userName, string password, string softwareVersion);
Login
方法显然是执行某些操作的东西 - 我猜它会创建票证。它绝对不适合 GET HTTP 请求。这绝对应该是对登录资源的 POST 请求,为每次调用返回新的 ITicket
表示。为什么?因为 GET 请求应该是安全和幂等的。
因为 HTTP GET 请求被 HTTP 基础设施认为是安全和幂等的,所以它以不同的方式处理。例如 GET 请求可以被缓存重定向等。当请求不安全和幂等时,它应该使用 POST 方法。所以正确的定义是:
[OperationContract]
[WebInvoke(UriTemplate = "/login?username={userName}&password={password}&softwareVersion={softwareVersion}", ResponseFormat=WebMessageFormat.Json)]
ITicket Login(string userName, string password, string softwareVersion);
因为 WebInvoke
默认为 POST 方法。这也是为什么所有协议(protocol)隧道(例如 SOAP)通常对所有请求使用 POST HTTP 方法的原因。
前一个示例中的另一个问题可能还是 REST 方法 = 充分利用 HTTP 基础架构。它应该使用基于 HTTP 的身份验证(登录)= Basic、Digest、OAuth 等。这并不意味着您不能拥有类似的资源,但您应该首先考虑使用标准的 HTTP 方式。
您的第二个示例实际上要好得多,但它存在 WCF 限制问题。 WCF 只能从 URL 中读取基本类型(顺便说一下,你想如何在 URL 中传递对象?)。任何其他参数类型都需要自定义 WCF 行为。如果您需要公开接受数据协定的方法,您必须再次使用在正文中接受参数的 HTTP 方法 - 再次使用 POST 并将 JSON 序列化票证放入请求正文:
[OperationContract]
[WebInvoke(UriTemplate = "/GetMetaData",RequestFormat=WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
IMetaData GetMetaData(ITicket ticket);
关于c# - 是否有使用 basicHttpBinding 扩展 WCF 服务以允许 REST 服务与 JSON 通信的好方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8167651/
大多数语言都支持双向进程通信。例如,在 Python 中,我可以(草率地)执行以下操作: >>> from subprocess import * >>> p = Popen('nslookup',
致力于使用 C++ 在 arduino 和 PC (Win 7) 之间进行通信。使用 WriteFile 和 ReadFile 创建通信或简单地发送或接收数据没有问题。但是当我想以某种方式“协调”沟通
我们正在开发一个基于微服务的应用程序。它们将使用 Helm Package Manager 部署到 kubernetes,并且它们都存储了自己的存储库和 helm chart。以下是我们微服务的名称。
我正在开发一个大型 MVVM 应用程序。我为此使用了 MVVM 轻量级工具包。该应用程序就像一个带有后退和前进按钮的网络浏览器。主视图是一个用户控件。我在主视图用户控件中放置了后退和前进按钮。主视图又
我在 java 和 freepascal(lazarus) 应用程序之间的通信有问题。我使用套接字。它们正确连接。一切都很顺利,直到我想从一个应用程序向另一个应用程序发送一些东西。在java而不是“a
我已经使用客户端套接字和服务器套接字使用C#编写了群聊。 当我使用VS 2017在自己的PC中运行程序(服务器和客户端)时,客户端和服务器之间的通信工作正常。 当我在笔记本电脑中运行客户端程序,并在自
Kubernetes 中两个不同 Pod 之间的通信是如何发生的? 就我而言,我有两个 Pod:前端和后端,它们都有不同的容器。 我希望我的前端 pod 与后端 pod 通信,但我不想使用后端 pod
我正在尝试在浏览器中嵌入的 flash 实例与在 C# WinForms 应用程序中运行的 flash 实例之间进行通信...我收到一个编译错误,内容为: 1119 Access of possibl
鉴于网络上缺乏信息,请问一个问题:我要在 Android 中创建一个应用程序,使用一个数据库应用程序 rails 。为此,我需要一个手动 session 。所以如果有人准备好了示例/教程显示通信 an
我正在编写一个应用程序,它将通过 MySQL 数据库对用户进行身份验证。我已经用 Java (android) 编写了它,但现在正在移植到 Windows 手机。 PHP 文件使用 $get 然后回显
是否可以通过互联网在两个不同设备上的两个不同应用程序之间建立通信。我想从设备 A 上的应用程序点击一个设备 B 上的应用程序,然后从设备 B 上的应用程序获取数据到设备 A 上的应用程序。如果可能,如
这是脚本: 它被放置在其他网站上。 com 并显示一个 iframe。如果有人点击 iframe 中的某个内容,脚本应该将一个 div 写入 othersite 。 com. 所以我的问题是如何做到
你好我是 php 的新手,我用 c++ 编写了整个代码并想在 php 中使用这段代码。所以我为我的代码制作了 dll 以使用它。但是我不能在 php 中使用这个 dll,可以谁能给我完整的代码来使用
我确定之前已经有人问过(并回答过)此类问题,所以如果是这样,请将我链接到之前的讨论... 在 C++ 中,假设我有一个 ClassA 类型的对象,其中包含一个 ClassB 类型的私有(private
我正在尝试使用 ATmega32 进行串行通信。首先,我使用 RS232,使用 USB-to-RS232 建立使用串行终端的接收和传输(在我的例子中是 tera 术语)。无论我从串行终端 Atmega
我找不到适用于 Ruby 的 SSL 实现。 我的部分项目需要服务器和客户端之间的安全通信链接,我希望为此使用 SSL 以创建安全 session 。 谢谢 最佳答案 如果你使用 Ruby 1.9.x
我正在尝试在客户端/服务器之间进行 SSL 通信。 到目前为止,我已经从 keystore 创建了 java.security.cert.X509Certificate。接下来我应该怎么做才能使这次沟
我在与 Windows 上的 USB 设备 通信时遇到问题。我不能使用 libusb 或 WinUSB,因为我有一个特定的驱动程序(Silabs USB 到 UART,这是一个 USB 到串口的桥接器
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
我发现 xcom 实际上是将数据写入数据库并从其他任务中提取数据。我的数据集很大,将其腌制并写入数据库会导致一些不必要的延迟。有没有办法在不使用 xcom 的情况下在同一 Airflow Dag 中的
我是一名优秀的程序员,十分优秀!