简体   繁体   English

调用WCF服务操作时HTTP 400 Bad Request?

[英]HTTP 400 Bad Request when calling WCF Service Operation?

When I call http://localhost/TestService.svc/GetColors , I get a Http (400) Bad Request. 当我调用http://localhost/TestService.svc/GetColors时 ,我得到一个Http(400)错误请求。 When I run this in fiddler, I also get Bad Request. 当我在小提琴手中运行时,我也得到了错误请求。 When I invoke the service through the wcf test client, it works fine though. 当我通过wcf测试客户端调用服务时,它工作正常。 What could cause this? 什么可能导致这个?

Service contract: 服务合约:

[ServiceContract]
public interface ITestService
{
    [OperationContract]
    string GetColors();
}

Implementation of ITestService: ITestService的实施:

[ServiceBehavior(InstanceContextMode=InstanceContextMode.Single)]
public class TestService : ITestService
{
    public List<Color> GetColors()
    {
        List<Color> colors= new List<Color>();

        colors.Add(new Color { Name = "Red", Code = "123" });
        colors.Add(new Color { Name = "Blue", Code = "323" });
        colors.Add(new Color { Name = "Green", Code = "3394" });

       return colors;
    }
}

Here is my web.config: 这是我的web.config:

<?xml version="1.0"?>
<configuration>
   <system.web>
       <compilation debug="true" targetFramework="4.0"/>
   </system.web>
   <system.serviceModel>
      <bindings>
         <wsHttpBinding>
            <binding name="CustomAuthentication">
               <security mode="Message">
                  <message clientCredentialType="UserName"/>
               </security>
            </binding>
         </wsHttpBinding>
      </bindings>
      <serviceHostingEnvironment multipleSiteBindingsEnabled="true"/>
      <services>
          <service name="TestService.TestService"
                behaviorConfiguration="CustomValidator" >
             <endpoint 
                 address="" 
                 binding="wsHttpBinding" 
                 bindingConfiguration="CustomAuthentication"
                 contract="TestService.ITestService">
                 <identity>
                    <dns value="localhost" />
                 </identity>
             </endpoint>
             <endpoint 
                 address="mex" 
                 binding="mexHttpBinding" 
                 contract="IMetadataExchange" />
             <host>
                 <baseAddresses>
                     <add baseAddress="http://localhost/TestService/" />
                 </baseAddresses>
             </host>
          </service>
      </services>
      <behaviors>
          <serviceBehaviors>
             <behavior name="CustomValidator">
                <serviceCredentials>
                   <userNameAuthentication userNamePasswordValidationMode="Custom"
                                customUserNamePasswordValidatorType="TestService.CustomUserNameValidator, TestService"/>
                   <serviceCertificate findValue="Test" storeLocation="LocalMachine" 
                         storeName="My" x509FindType="FindBySubjectName"/>
                </serviceCredentials>
                <serviceMetadata httpGetEnabled="True"/>
             </behavior>
             <behavior>
                <serviceMetadata httpGetEnabled="True"/>
                <serviceDebug includeExceptionDetailInFaults="False"/>
             </behavior>
         </serviceBehaviors>
      </behaviors>
   </system.serviceModel>
   <system.webServer>
       <modules runAllManagedModulesForAllRequests="true"/>
   </system.webServer>
</configuration>

When I call it, I just open up a any browser and put the url http://localhost/TestService.svc/GetColors . 当我调用它时,我只需打开一个浏览器并输入URL http://localhost/TestService.svc/GetColors If I do it through the dev environment, I see the Http 400 bad request. 如果我通过开发环境这样做,我会看到Http 400错误的请求。 If I do it through IIS, I just see a blank page. 如果我通过IIS执行此操作,我只会看到一个空白页面。

Here is the InnerException: 这是InnerException:

<ExceptionString>System.Xml.XmlException: The body of the message cannot be read  
because it is empty.</ExceptionString>

Another question regarding my CustomUserNameValidation: 关于我的CustomUserNameValidation的另一个问题:

I am implementing Custom Validation through the Validate Method of UserNamePasswordValidator, but when I call something like GetColors through the wcf client, it does not invoke the Validate method. 我正在通过UserNamePasswordValidator的Validate方法实现Custom Validation,但是当我通过wcf客户端调用类似GetColors的东西时,它不会调用Validate方法。 The only way I can get it to Invoke validate is if I call Validate(user,pass) directly in GetColors. 我可以将它调用Invoke验证的唯一方法是在GetColors中直接调用Validate(user,pass)。 I thought it woulld be called automatically for every service call if you have it setup correctly in web.config. 如果你在web.config中正确设置它,我认为它可以自动调用每个服务调用。

Your service contract and service implementation don't seem to match.... 您的服务合同和服务实施似乎不匹配....

The service contract defines a single string to be returned from GetColors() : 服务契约定义了从GetColors()返回的单个string

[ServiceContract]
public interface ITestService
{
    [OperationContract]
    string GetColors();
}

But the implementation returns a List<Color> instead: 但实现返回List<Color>

[ServiceBehavior(InstanceContextMode=InstanceContextMode.Single)]
public class TestService : ITestService
{
    public List<Color> GetColors()
    {

Is there any chance you changed your service implementation, and forgot to update the service contract?? 你有没有机会改变你的服务实现,忘了更新服务合同?

Also: since this is a SOAP service with a wsHttpBinding , you cannot just call the method from a browser by browsing to its address - you need to use the WCF Test Client (which works, as you say). 另外:由于这是一个带有wsHttpBinding的SOAP服务,你不能只通过浏览到它的地址从浏览器调用该方法 - 你需要使用WCF测试客户端(如你所说,它可以工作)。 Nor can you just call it from Fiddler, either - you would have to manually create the entire SOAP envelope with header and body and all - not an easy task at all. 你也不能从Fiddler那里调用它 - 你必须手动创建带有标题和正文的整个SOAP信封 - 这根本不是一件容易的事。

What you can try is to go to http://localhost/TestService.svc?wsdl to check whether you'll get back the proper WSDL for the service. 您可以尝试访问http://localhost/TestService.svc?wsdl以检查您是否将获得该服务的正确WSDL。

Many things could cause this. 很多事情都可能导致这一点 I suggest you first enable WCF Tracing, it's usually very helpful as it gives you the server side output of what's really going on. 我建议你首先启用WCF跟踪,它通常非常有用,因为它为你提供了实际发生的服务器端输出。 Here is a link that should help: How to enable WCF tracing 这是一个应该有用的链接: 如何启用WCF跟踪

EDIT : One little thing to note with WCF: unlike auto generated ole' ASMX web service it does not allow you to browse to the base address with a standard browser. 编辑 :WCF需要注意的一件事:与自动生成的'ASMX Web服务不同,它不允许您使用标准浏览器浏览到基址。 You can browse to the Metadata address (the mex one), but not to the root. 您可以浏览到元数据地址(mex),但不能浏览到根目录。 This is just by design (the HTTP method is not supported I believe). 这只是设计(我相信不支持HTTP方法)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM