意图:我需要从自动化服务器组向数据库提交一系列测试报告。测试脚本在 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 使用。该站点设置了特定的应用程序池,并且服务器设置在使用 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 的浏览器调用中,我知道 <string xmlns='http://schemas.microsoft.com/2003/10/Serialization/'>
正是我所期待的...所以我现在需要找出连接到此 WCF REST 服务所需的 powershell。
编辑:
使用 svcutil.exe 实用程序创建代理,但跳过配置文件。行 serviceMetadata httpGetEnabled="true"
意味着我正在生成可用于 WCF 客户端的元数据?这会影响PS吗?
最佳答案
New-WebServiceProxy 为 web 服务(例如 .NET 中的 .asmx)创建一个“web 服务”代理。这些类型的服务是 WS-I-Basic Profile 1.1 服务。换句话说,有对 WSDL 的期望。
您的WCF 服务 只有一个端点,即 WebHttpBinding 端点。这种端点用于 HTTP 客户端(非 soap),通常由 REST 客户端使用,因为它们仅使用 Web 协议(protocol)(HTTP 和适当的动词,如 GET、POST 等)。当您使用浏览器对此进行测试时,它起作用了,因为浏览器只是 HTTP 客户端。当您使用来自 New-WebServiceProxy 的代理对其进行测试时,它会尝试将响应解释为 WSDL 而不仅仅是字符串,因为这是 New-WebServiceProxy 创建的客户端类型。
要使您的 WCF 服务 为 Web 服务 客户端(例如 New-WebServiceProxy)工作,您需要使用它们理解的绑定(bind)为这些客户端添加另一个端点,这是 basicHttpBinding。
<endpoint address="basic" binding="basicHttpBinding" contract="TrendDB.Web.ITrendRestService" />
这至少会使其适用于两种类型的客户端(减去安全性)。
为了安全起见,为 basicHttpBinding 创建一个 BindingConfiguration,为 webHttpBinding 创建一个。在那里,您可以将客户端凭据类型指定为 Windows。
关于c# - Powershell 如何通过 IIS 使用 WCF REST 服务?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18221096/