通过http将肥皂消息发布到WCF服务错误400

时间:2017-03-27 10:32:05

标签: c# wcf soap

我目前有2个应用:

  1. WCF服务
  2. 触发对我的WCF服务的HTTP请求的控制台应用
  3. 我想将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>";
    

4 个答案:

答案 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>

它对我有用......