我目前有2个应用:
我想将SOAP消息发送到我的WCF服务并解析从WCF服务返回的XML数据。我可以使用纯XML和此端点URL http://localhost:62147/Service1.svc/Http/成功进行GET和POST,但使用SOAP它无法正常工作。发送请求时出现以下错误。
异常
An unhandled exception of type 'System.Net.WebException' occurred in System.dll
Additional information: The remote server returned an error: (400) Bad Request.
WCF服务web.config
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5"/>
</system.web>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- To avoid disclosing metadata information, set the values below to false before deployment -->
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service name="WcfService1.Service1">
<endpoint address="Soap" binding="basicHttpBinding" contract="WcfService1.IService1" />
<endpoint address="Http" kind="webHttpEndpoint" contract="WcfService1.IService1" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<httpErrors errorMode="Detailed"/>
</system.webServer>
</configuration>
WCF IService1
[ServiceContract]
public interface IService1
{
[OperationContract]
[WebInvoke]
string GetData(string channel);
}
控制台应用
private static string HttpPost(string _postData)
{
using (WebClient webClient = new WebClient())
{
webClient.BaseAddress = "http://localhost:62147/Service1.svc/Soap/";
webClient.Headers.Add("Content-Type", "text/xml; charset=utf-8");
webClient.Headers.Add("SOAPAction", "http://tempuri.org/IService1/GetData");
byte[] response = webClient.UploadData("GetData", Encoding.UTF8.GetBytes(_postData));
return Encoding.UTF8.GetString(response);
}
}
肥皂消息 我从WCF测试客户端复制了它。
const string soapMsg = @"
<s:Envelope xmlns:s=""http://schemas.xmlsoap.org/soap/envelope/"">
<s:Header>
<Action s:mustUnderstand=""1"" xmlns=""http://schemas.microsoft.com/ws/2005/05/addressing/none"">http://tempuri.org/IService1/GetData</Action>
</s:Header>
<s:Body>
<GetData xmlns=""http://tempuri.org/"">
<channel>1</channel>
</GetData>
</s:Body>
</s:Envelope>";
答案 0 :(得分:1)
我认为问题在于如何将XML数据附加到请求中。这是我对WebGet的工作示例。这也适用于WebInvoke方法,但当然,只需要用预期的参数修改soap体
控制台应用
private static void TestGet()
{
Console.WriteLine("[TestGet]\n");
const string soapMsg = @"<SOAP-ENV:Envelope xmlns:SOAP-ENV=""http://schemas.xmlsoap.org/soap/envelope/""
xmlns:xsi=""http://www.w3.org/1999/XMLSchema-instance""
xmlns:xsd=""http://www.w3.org/1999/XMLSchema"">
<SOAP-ENV:Body>
<TestGet xmlns=""http://tempuri.org/"" SOAP-ENV:encodingStyle=""http://schemas.xmlsoap.org/soap/encoding/"" />
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>";
PerformSOAPRequest(URL, "TestGet", soapMsg);
}
public static void PerformSOAPRequest(string _url, string _method, string xml_message)
{
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(_url);
webRequest.Accept = "text/xml";
webRequest.ContentType = "text/xml;charset=\"utf-8\"";
webRequest.Headers.Add(@"SOAPAction", string.Format("http://tempuri.org/IService1/{0}", _method));
webRequest.Method = "POST";
byte[] bytes = Encoding.UTF8.GetBytes(xml_message);
webRequest.ContentLength = bytes.Length;
using (Stream putStream = webRequest.GetRequestStream())
{
putStream.Write(bytes, 0, bytes.Length);
}
using (WebResponse response = webRequest.GetResponse())
using (StreamReader rd = new StreamReader(response.GetResponseStream()))
{
string soapResult = rd.ReadToEnd();
Console.WriteLine(soapResult);
}
}
WCF中的IService1
[ServiceContract]
public interface IService1
{
[OperationContract]
[WebGet(BodyStyle = WebMessageBodyStyle.Wrapped,
RequestFormat = WebMessageFormat.Xml,
ResponseFormat = WebMessageFormat.Xml,
UriTemplate = "/TestGet")]
string TestGet();
}
答案 1 :(得分:0)
尝试添加编码声明:也在interface Foo {
readonly bar: () => void;
}
内。
soapMsg
您需要向SOAP服务发出GET请求,您已使用 const string soapMsg = @"
<?xml version=""1.0"" encoding=""UTF-8""?>
<s:Envelope xmlns:s=""http://schemas.xmlsoap.org/soap/envelope/"">
<s:Header>
<Action s:mustUnderstand=""1"" xmlns=""http://schemas.microsoft.com/ws/2005/05/addressing/none"">http://tempuri.org/IService1/GetData</Action>
</s:Header>
<s:Body>
<GetData xmlns=""http://tempuri.org/"">
<channel>1</channel>
</GetData>
</s:Body>
</s:Envelope>";
属性修饰了GetData
方法,其默认HTTP方法为GET。
尝试使用WebMethod
方法而不是DownloadString
,因为默认情况下UploadData
使用POST方法发出请求。但是,您需要将属性UploadData
更改为WebGet。
答案 2 :(得分:0)
考虑使用HttpWebRequest和WebResponse而不是WebClient
public static void PerformSOAPRequest(string xml_message)
{
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(@"http://localhost:62147/Service1.svc/Soap/");
webRequest.Headers.Add(@"SOAPAction", "http://tempuri.org/IService1/GetData");
webRequest.ContentType = "text/xml;charset=\"utf-8\"";
webRequest.Accept = "text/xml";
webRequest.Method = "POST";
XmlDocument soapEnvelopeXml = new XmlDocument();
soapEnvelopeXml.LoadXml(xml_message);
using (Stream stream = webRequest.GetRequestStream())
{
soapEnvelopeXml.Save(stream);
}
using (WebResponse response = webRequest.GetResponse())
{
using (StreamReader rd = new StreamReader(response.GetResponseStream()))
{
string soapResult = rd.ReadToEnd();
Console.WriteLine(soapResult);
}
}
}
答案 3 :(得分:0)
你需要从SOAP信封中删除行:
<s:Header>
<Action s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://tempuri.org/IService1/GetData</Action>
</s:Header>
它对我有用......