尝试使用WebRequest调用WCF服务

问题描述:

我有一个WCF服务,需要由第三方应用程序调用,发布一些原始XML。尝试使用WebRequest调用WCF服务

我想通过构建一个简单的WebRequest并向服务发出请求来测试我的服务。

这里是我的服务代码:

接口:

[ServiceContract(Namespace = "http://test.mydomain.com")] 
public interface ITest 
{ 
    [WebInvoke(UriTemplate = "", BodyStyle = WebMessageBodyStyle.Bare, Method="POST")] 
    [OperationContract] 
    Stream SaveXML(Stream input); 
} 

服务:

[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)] 
[ServiceBehavior(Namespace = "http://test.mydomain.com")] 
public class Test : ITest 
{ 
    public Stream SaveXML(Stream input) 
    { 
     StreamReader streamReader = new StreamReader(input); 
     string rawString = streamReader.ReadToEnd(); 
     streamReader.Dispose(); 

     // here need to save the input stream to xml format file 
     Encoding encoding = Encoding.GetEncoding("ISO-8859-1"); 
     WebOperationContext.Current.OutgoingResponse.ContentType = "text/xml"; 
     byte[] returnBytes = encoding.GetBytes(rawString); 
     return new MemoryStream(returnBytes); 
    } 
} 

配置:

<services> 
    <service behaviorConfiguration="Blah.TestBehavior" name="Blah.Test"> 
    <endpoint address="http://localhost:51494/Blah/Test.svc" binding="basicHttpBinding" contract="Blah.ITest"> 
     <identity> 
     <dns value="localhost" /> 
     </identity> 
    </endpoint> 
    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /> 
    </service> 
</services> 

错误的客户端代码:

  string postData = "<Message version=\"1.5\" xmlns=\"http://test.mydomain.com\" ><books>Blah</books></Message>"; 
     WebRequest request = WebRequest.Create("http://localhost:51494/Blah/Test.svc/SaveXML"); 
     request.Method = "POST"; 

     byte[] byteArray = Encoding.UTF8.GetBytes(postData); 
     request.ContentType = "application/x-www-form-urlencoded"; 
     //request.ContentType = "text/xml; charset=utf-8"; 
     //request.ContentType = "text/xml;"; 
     //request.ContentType = "application/xml;"; 
     request.ContentLength = byteArray.Length; 

     Stream dataStream = request.GetRequestStream(); 
     dataStream.Write(byteArray, 0, byteArray.Length); 
     dataStream.Close(); 

     // Get the response. 
     WebResponse response = request.GetResponse(); 

在最后一行我得到一个400(坏请求)或415(不支持的媒体类型)错误,这取决于我的contentType指定。另外,如果我在我的客户端应用程序中添加服务引用,并使用API​​调用服务,那么它可以正常工作。任何见解都将不胜感激,因为我是WCF的新手,并且完全陷入困境。

+0

我会做什么:使用Fiddler http://fiddler2.com/fiddler2/来查看“API”的请求 - 一个工程。然后将它与不起作用的请求进行比较。这应该缩小它的范围。 – Cheeso 2010-03-04 20:49:17

+0

您的'StreamReader'需要位于'using'块中,就像其他几个对象一样。即使抛出异常,'使用'块也会导致它们被丢弃。 – 2010-03-04 21:23:41

我觉得你在这里混淆了两个不同的东西:

  1. WebRequestPOST[WebInvoke]属性建议你试图做类似REST
  2. 但是你的服务配置有basicHttpBinding - 这不会WebRequest

飞SOAP协议,这样 - 让你的心!

你想使用SOAP吗?然后你基本上可以正常使用basicHttpBinding,但是你不能像使用POST的WebRequest那样访问SOAP服务 - 你需要在命令行中使用由Visual Studio或svcutil.exe生成的SOAP客户端。

你想使用WebRequest和简单的POST请求?然后,您需要创建基于REST的WCF服务 - 使用webHttpBindingWebServiceHost(而不是简单的ServiceHost)。

对于基于SOAP的WCF服务,请查看WCF Developer Center on MSDN

对于基于REST的WCF服务(您可以在浏览器中导航到您可以从WebRequest调用的服务),请查看WCF REST Developer Center on MSDN并查看WCF中基于REST的优秀screencast series by Pluralsight - 最值得注意的:

+0

WCF开发人员中心似乎已停用 - 任何更新的链接都可用? – Default 2017-08-08 10:03:23

+0

..而且不幸的是RESTful视频。 – Default 2017-08-08 10:35:12

+0

@Default:对不起,这些链接没问题 - 在** 2010 **的时候我回答了 - 但你说得对,他们似乎已经死了。对不起,我没有任何替代链接.....试着问Google或Bing,也许? – 2017-08-08 11:04:24

basicHttpBinding的也适合!

我花了差不多一天搞清楚什么是错用的WebRequest与basicHttpBinding的WCF服务,它原来我错过了小而关键的东西:的SOAPAction头已被设置!

newRequest.Headers["SOAPAction"] = "http://tempuri.org/INotificationService/MyMethodName" 
+0

你在“WebRequest”的主体中提供了什么。它是否包含SOAPHeaders? – Abhijeet 2013-08-21 17:02:26

+0

@autrevo,你的意思是请求流?您可以安装http代理(如Fiddler)并检查WCF服务调用中发送的内容。您将看到请求正文和标题。我不得不在我的任务中提出请求,所以我不会自己构造请求主体。 – ADOConnection 2013-08-22 12:46:37