C#WCF“System.Net.WebException:远程服务器返回错误:(400)错误请求。”

时间:2017-03-19 09:51:12

标签: c# asp.net .net wcf

我收到“System.Net.WebException:远程服务器在尝试访问我的WCF方法时返回错误:(400)Bad Request”错误。我认为可能是在客户端。当我使用促销标准工具验证它时,它工作正常http://services.promostandards.org/webserviceValidator/home

以下是来自WCF和客户的信息。

WCF配置文件

<system.serviceModel>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true">
    </serviceHostingEnvironment>

    <bindings>
      <basicHttpBinding>
        <binding name="basicHttpBindingConfig" messageEncoding="Text" textEncoding="utf-8">
          <security mode="None">
            <transport clientCredentialType="None" proxyCredentialType="None"/>
          </security>
        </binding>
        <binding name="basicHttpBindingConfig2" messageEncoding="Text" textEncoding="utf-8">
          <security mode="None">
            <transport clientCredentialType="None" proxyCredentialType="None"/>
          </security>
        </binding>
        <binding name="basicHttpBindingConfig3" messageEncoding="Text" textEncoding="utf-8">
          <security mode="None">
            <transport clientCredentialType="None" proxyCredentialType="None"/>
          </security>
        </binding>
        <binding name="basicHttpBindingConfig4" messageEncoding="Text" textEncoding="utf-8">
          <security mode="None">
            <transport clientCredentialType="None" proxyCredentialType="None"/>
          </security>
        </binding>
      </basicHttpBinding>
    </bindings>


    <services>
      <!-- Note: the service name must match the configuration name for the service implementation. -->
      <service name="Proactive_WebAPI.Services.Product"  behaviorConfiguration="ProductDataServiceBehavior">
        <!-- Add the following endpoint.  -->
        <!-- Note: your service must have an http base address to add this endpoint. -->
        <endpoint
            address="http://api.proactiveclothing.com/services/Product.svc"
            binding="basicHttpBinding"
            bindingConfiguration="basicHttpBindingConfig"
            contract="Proactive.Product.ProductDataService" 
            listenUri="/"/>
      </service>
      <service name="Proactive_WebAPI.Services.Media"  behaviorConfiguration="MediaContentServiceBehavior">
        <!-- Add the following endpoint.  -->
        <!-- Note: your service must have an http base address to add this endpoint. -->
        <endpoint
            address="http://api.proactiveclothing.com/services/Media.svc"
            binding="basicHttpBinding"
            bindingConfiguration="basicHttpBindingConfig2"
            contract="Proactive.Media.MediaContentService" 
            listenUri="/"/>
      </service>
      <service name="Proactive_WebAPI.Services.PricingAndConfiguration"  behaviorConfiguration="PricingAndConfigurationBehavior">
        <!-- Add the following endpoint.  -->
        <!-- Note: your service must have an http base address to add this endpoint. -->
        <endpoint
            address="http://api.proactiveclothing.com/services/PricingAndConfiguration.svc"
            binding="basicHttpBinding"
            bindingConfiguration="basicHttpBindingConfig2"
            contract="Proactive.Pricing.PricingAndConfigurationService" 
            listenUri="/"/>
      </service>
      <service name="Proactive_WebAPI.Services.Inventory"  behaviorConfiguration="InventoryServiceBehavior">
        <!-- Add the following endpoint.  -->
        <!-- Note: your service must have an http base address to add this endpoint. -->
        <endpoint
            address="http://api.proactiveclothing.com/services/Inventory.svc"
            binding="basicHttpBinding"
            bindingConfiguration="basicHttpBindingConfig4"
            contract="Proactive.Inventory.InventoryService" 
            listenUri="/"/>
      </service>
    </services>

    <behaviors>
      <serviceBehaviors>
        <behavior name="ProductDataServiceBehavior" >
          <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
          <serviceMetadata httpGetEnabled="true" externalMetadataLocation="http://api.proactiveclothing.com/wsdl/ProductDataService.wsdl"/>
          <!-- 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="true"/>
        </behavior>
        <behavior name="MediaContentServiceBehavior" >
          <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
          <serviceMetadata httpGetEnabled="true" externalMetadataLocation="http://api.proactiveclothing.com/wsdl/MediaContentService.wsdl"/>
          <!-- 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="true"/>
        </behavior>
        <behavior name="PricingAndConfigurationBehavior" >
          <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
          <serviceMetadata httpGetEnabled="true" externalMetadataLocation="http://api.proactiveclothing.com/wsdl/PricingAndConfiguration.wsdl"/>
          <!-- 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="true"/>
        </behavior>
        <behavior name="InventoryServiceBehavior" >
          <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
          <serviceMetadata httpGetEnabled="true" externalMetadataLocation="http://api.proactiveclothing.com/wsdl/InventoryService.wsdl"/>
          <!-- 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="true"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>

  </system.serviceModel>

客户代码

private string Connect_WebRequest()
    {
        ASCIIEncoding encoding = new ASCIIEncoding();
        string SampleXml = "<GetProductSellableRequest xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns=\"http://www.promostandards.org/WSDL/ProductDataService/1.0.0/\">";
               SampleXml += "<wsVersion xmlns=\"http://www.promostandards.org/WSDL/ProductDataService/1.0.0/SharedObjects/\">Token1</wsVersion>";
               SampleXml += "<id xmlns=\"http://www.promostandards.org/WSDL/ProductDataService/1.0.0/SharedObjects/\">Token1</id>";
               SampleXml += "<password xmlns=\"http://www.promostandards.org/WSDL/ProductDataService/1.0.0/SharedObjects/\">xxxx</password>";
               SampleXml += "<productId xmlns=\"http://www.promostandards.org/WSDL/ProductDataService/1.0.0/SharedObjects/\">Token1</productId>";
               SampleXml += "<partId xmlns=\"http://www.promostandards.org/WSDL/ProductDataService/1.0.0/SharedObjects/\">Token1</partId>";
               SampleXml += "<isSellable xmlns=\"http://www.promostandards.org/WSDL/ProductDataService/1.0.0/SharedObjects/\">true</isSellable>";
               SampleXml += "</GetProductSellableRequest>";

        string postData = SampleXml.ToString();
        byte[] data = encoding.GetBytes(postData);

        string url = "http://api.proactiveclothing.com/services/Product.svc/getProductSellable";

        string strResult = string.Empty;

        // declare httpwebrequet wrt url defined above
        HttpWebRequest webrequest = (HttpWebRequest)WebRequest.Create(url);
        // set method as post
        webrequest.Method = "POST";
        // set content type
        webrequest.ContentType = "text/xml";
        // set content length
        webrequest.ContentLength = data.Length;
        // get stream data out of webrequest object
        Stream newStream = webrequest.GetRequestStream();
        newStream.Write(data, 0, data.Length);
        newStream.Close();

        //Gets the response
        WebResponse response = webrequest.GetResponse();
        //Writes the Response
        Stream responseStream = response.GetResponseStream();

        StreamReader sr = new StreamReader(responseStream);
        string s = sr.ReadToEnd();

        return s;
    }

1 个答案:

答案 0 :(得分:1)

你缺少两件事。将您的xml包装在soap Envelope中,并为要调用的端点添加SOAPAction标头。在这种情况下,“getProductSellable”:

class Program
{
    static void Main(string[] args)
    {

        ASCIIEncoding encoding = new ASCIIEncoding();

        string SampleXml = @"<s:Envelope xmlns:s=""http://schemas.xmlsoap.org/soap/envelope/"">
            <s:Body xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"">
                <GetProductSellableRequest xmlns=""http://www.promostandards.org/WSDL/ProductDataService/1.0.0/"">
                    <wsVersion xmlns=""http://www.promostandards.org/WSDL/ProductDataService/1.0.0/SharedObjects/"">1.0.0</wsVersion>
                    <id xmlns=""http://www.promostandards.org/WSDL/ProductDataService/1.0.0/SharedObjects/"">Token1</id>
                    <password xmlns=""http://www.promostandards.org/WSDL/ProductDataService/1.0.0/SharedObjects/"">Token1</password>
                    <productId xmlns=""http://www.promostandards.org/WSDL/ProductDataService/1.0.0/SharedObjects/"">Token1</productId>
                    <partId xmlns=""http://www.promostandards.org/WSDL/ProductDataService/1.0.0/SharedObjects/"">token1</partId>
                    <isSellable xmlns=""http://www.promostandards.org/WSDL/ProductDataService/1.0.0/SharedObjects/"">true</isSellable>
                </GetProductSellableRequest>
            </s:Body>
        </s:Envelope>";

        try
        {
            byte[] data = encoding.GetBytes(SampleXml);

            string url = "http://api.proactiveclothing.com/services/Product.svc";

            HttpWebRequest webrequest = (HttpWebRequest)WebRequest.Create(url);
            webrequest.Method = "POST";
            webrequest.Headers.Add("SOAPAction", "getProductSellable");
            webrequest.ContentType = "text/xml";
            webrequest.ContentLength = data.Length;

            using (Stream newStream = webrequest.GetRequestStream())
            {
                newStream.Write(data, 0, data.Length);

                using (WebResponse response = webrequest.GetResponse())
                using (Stream responseStream = response.GetResponseStream())
                {
                    StreamReader sr = new StreamReader(responseStream);
                    string s = sr.ReadToEnd();
                    Console.WriteLine(s);
                }
            }

        }
        catch (WebException webex)
        {
            Console.WriteLine(webex.Message);
        }

        Console.ReadKey();
    }
}

对于您的PHP客户端,您可以执行以下操作:使用位于此处的WSDL:http://api.proactiveclothing.com/wsdl/ProductDataService.wsdl (但是,如果你向他们提供wsdl,他们应该知道如何做到这一点)

  

未测试

<?php
 
    $arr = array(
        'GetProductSellableRequest' => 
            array(
                'wsVersion' => ????,
                'id' => ?????,
                'password' => ?????,
                'productId' => ????,
                'partId' => ????,
                'isSellable' => ????        
    );
     

        try {
            $sc = new SoapClient("ProductDataService.wsdl", array(
                'location' => 'http://api.proactiveclothing.com/services/Product.svc')
             );

            $resp = $sc-> Submit($arr); 
        
            echo(var_dump($resp));
        }
        catch (SoapFault $fault) {
            echo(var_dump($fault));
        }
?>