【发布时间】:2017-03-19 09:51:11
【问题描述】:
我在尝试访问我的 WCF 方法时收到“System.Net.WebException:远程服务器返回错误:(400) 错误请求”错误。我认为它可能在客户端。当我使用促销标准工具对其进行验证时,它可以正常工作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;
}
【问题讨论】:
-
首先,我建议激活跟踪(在客户端和服务器端,因为您似乎可以控制两者)。这可能会提供有关 400 错误的更多详细信息:msdn.microsoft.com/en-us/library/ms733025(v=vs.110).aspx
-
以这种方式发送请求时,没有必要进行客户端绑定。您的请求显然不是 SOAP 信封,所以我认为这是“错误请求”的原因
-
@Crowcoder 指出。我想我粘贴了它,因为我在测试时首先将服务添加为服务参考。我正在测试通过 WebRequest 进行连接。请忽略客户端配置代码。
-
@Crowcoder 我删除了客户端配置中对 WCF 的所有引用,因为 WebRequests 不需要它,但仍然有相同的错误:/
-
我并不是要暗示这是你的问题。