【问题标题】:How can Powershell consume WCF REST Service through IIS?Powershell 如何通过 IIS 使用 WCF REST 服务?
【发布时间】:2013-08-13 23:50:28
【问题描述】:

意图:我需要将一系列测试报告从自动化服务器组提交到数据库。测试脚本在 python 中,而不是打开那个蠕虫罐,我想设置一个 Powershell 脚本来将完成的测试推送到 WCF 服务。

我有一个现有的 ASP.NET 网站来管理报告并以此为基础,我想添加一个可以通过自动化访问的简单 WCF 服务。不过,我似乎遇到了困难,并且觉得我非常接近于完成这项工作。我已经在这个问题上工作了几天,在尝试寻找相关帮助时,我的眼睛开始流血。

服务代码:

namespace TrendDB.Web
{
    [ServiceContract]
    public interface ITrendRestService
    {
        [OperationContract]
        [WebGet]
        string GetTestMessage();
    }

    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    public class TrendRestService : ITrendRestService
    {
        public string GetTestMessage()
        {
            return "Success!";
        }
    }
}

Web.config(仅显示相关信息):

<system.web>
...
  <authentication mode="Windows" />
  <authorization>
    <deny users="?" />
  </authorization>
...
</system.web>
...
<system.serviceModel>
  <behaviors>
    <serviceBehaviors>
      <behavior name="">
        <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
        <serviceDebug includeExceptionDetailInFaults="false" />
      </behavior>
    </serviceBehaviors>
    <endpointBehaviors>
      <behavior name="restfulBehavior">
        <webHttp/>
      </behavior>
    </endpointBehaviors>
  </behaviors>
  <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
  <services>
    <service name="TrendDB.Web.TrendRestService">
      <endpoint address="" behaviorConfiguration="restfulBehavior"
                binding="webHttpBinding" bindingConfiguration="" contract="TrendDB.Web.ITrendRestService">
      </endpoint>
    </service>
  </services>
</system.serviceModel>

我在我的浏览器中以http://localhost/trenddb/TrendRestService.svc/GetTestMessage 进行了测试,得到的消息是:

<string xmlns="http://schemas.microsoft.com/2003/10/Serialization/">Success!</string>

IIS 7.5 是使用 MS 的 BKM 设置的,以便 MVC 使用 Intranet 的角色授权。该站点设置了特定的应用程序池,并且使用 Windows 身份验证在域中设置了服务器。

我对 Powershell 的第一次调用开始于:

$trend = New-WebServiceProxy -uri http://localhost/trenddb/TrendRestService.svc

New-WebServiceProxy : The request failed with HTTP status 401: Unauthorized.

这很好,因为至少这是对匿名访问的预设响应,所以我在命令中添加了-UseDefaultCredential并得到:

$trend = New-WebServiceProxy -uri http://localhost/trenddb/TrendRestService.svc -UseDefaultCredential
New-WebServiceProxy : Object reference not set to an instance of an object.

我尝试使用GetTestMessage WebInvoke 只是为了看看发生了什么:

$trend = New-WebServiceProxy -uri http://localhost/trenddb/TrendRestService.svc/GetTestMessage -UseDefaultCredential
New-WebServiceProxy : The document at the url 
http://localhost/trenddb/TrendRestService.svc/GetTestMessage was not recognized as a known document type.
The error message from each known type may help you fix the problem:
- Report from 'WSDL Document' is 'There is an error in XML document (1, 2).'.
  - <string xmlns='http://schemas.microsoft.com/2003/10/Serialization/'> was not expected.
- Report from 'XML Schema' is 'The root element of a W3C XML Schema should be <schema> and its namespace should be 'http://www.w3.org/2001/XMLSchema'.'.
- Report from 'DISCO Document' is 'Discovery document at the URL http://localhost/trenddb/TrendRestService.svc/GetTestMessage could not be found.'.
  - The document format is not recognized.

从我的浏览器调用到 WCF,我知道 &lt;string xmlns='http://schemas.microsoft.com/2003/10/Serialization/'&gt; 正是我所期望的......所以我现在需要弄清楚连接到这个 WCF REST 服务所需的 powershell。

编辑: 使用 svcutil.exe 实用程序会创建一个代理,但会跳过配置文件。 serviceMetadata httpGetEnabled="true" 行是否意味着我正在生成可用于 WCF 客户端的元数据?这会影响PS吗?

【问题讨论】:

  • 只是检查一下,您没有以管理员身份运行 PS 控制台,是吗?我想知道是不是DefaultCredential 造成了这种情况。
  • 使用 Fiddler 捕获从您的网络浏览器发出的请求,然后类似地捕获来自 PS 的请求并比较它们以查看导致问题的不同之处
  • @SrikanthVenugopalan - 我没有以管理员身份运行它,我以管理员身份再次尝试并使用相同的消息/行为。
  • @Rajesh - 对于网络浏览器来说很简单,但我不明白如何让 Fiddler 检查 PS 会话。我可能倾向于只编写一个快速的可执行文件来与服务器对话并调用它。
  • 当您运行 Fiddler 时,它会捕获所有来自浏览器或可执行文件的流量。您只需要从左窗格中识别 URL 并在右上方窗格中查看原始请求。

标签: c# wcf iis-7.5 powershell-3.0


【解决方案1】:

New-WebServiceProxy 为Web 服务 创建一个“Web 服务”代理(例如 .NET 中的 .asmx)。这些类型的服务是 WS-I-Basic Profile 1.1 服务。换句话说,就是对 WSDL 的期望。

您的WCF 服务只有一个端点,即 WebHttpBinding 端点。这种端点用于 HTTP 客户端(非肥皂),通常由 REST 客户端使用,因为它们仅使用 Web 协议(HTTP 和适当的动词,如 GET、POST 等)。当您使用浏览器对此进行测试时,它可以正常工作,因为浏览器只是 HTTP 客户端。当您使用来自 New-WebServiceProxy 的代理对其进行测试时,它会尝试将响应解释为 WSDL 而不仅仅是字符串,因为这是 New-WebServiceProxy 创建的客户端类型。

要使您的 WCF 服务Web 服务 客户端(例如 New-WebServiceProxy)工作,您需要使用他们理解的绑定为这些客户端添加另一个端点,这是基本的HttpBinding。

      <endpoint address="basic" binding="basicHttpBinding" contract="TrendDB.Web.ITrendRestService" />

这至少可以让它为两种类型的客户端工作(减去安全性)。

为了安全起见,为 basicHttpBinding 创建一个 BindingConfiguration,为 webHttpBinding 创建一个。在那里,您可以将客户端凭据类型指定为 Windows。

【讨论】:

  • 很好的答案,瑞克。格雷格可能不喜欢它,但我喜欢。
  • @Brian :至于“Greg 可能不欣赏它”,我假设您的意思是我可能不完全欣赏 Rick 提供的东西,但这是我对我致力于克服和对答案不乏感激之情。我认为这个解决方案正是我所需要的。在我提出任何问题或提供回复之前,我没有足够的时间重新开始实施它,并希望有时间来处理它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-02-03
  • 2011-08-12
  • 2017-02-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-23
相关资源
最近更新 更多